mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-09-14 02:29:29 +00:00
ChibiOS 2.6.8, until I can figure out where to get it from git.
This commit is contained in:
+1410
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,832 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 SPC5xx/edma.h
|
||||
* @brief EDMA helper driver header.
|
||||
*
|
||||
* @addtogroup SPC5xx_EDMA
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _SPC5_EDMA_H_
|
||||
#define _SPC5_EDMA_H_
|
||||
|
||||
#if SPC5_HAS_EDMA
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief EDMA channel allocation error.
|
||||
*/
|
||||
#define EDMA_ERROR -1
|
||||
|
||||
/**
|
||||
* @name EDMA mode constants
|
||||
* @{
|
||||
*/
|
||||
#define EDMA_TCD_MODE_START (1U << 0)
|
||||
#define EDMA_TCD_MODE_INT_END (1U << 1)
|
||||
#define EDMA_TCD_MODE_INT_HALF (1U << 2)
|
||||
#define EDMA_TCD_MODE_DREQ (1U << 3)
|
||||
#define EDMA_TCD_MODE_ACTIVE (1U << 6)
|
||||
#define EDMA_TCD_MODE_DONE (1U << 7)
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Default EDMA CR register initialization.
|
||||
*/
|
||||
#if !defined(SPC5_EDMA_ERROR_HANDLER) || defined(__DOXYGEN__)
|
||||
#define SPC5_EDMA_CR_SETTING 0x0000C400
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EDMA critical error handler, must not return.
|
||||
*/
|
||||
#if !defined(SPC5_EDMA_ERROR_HANDLER) || defined(__DOXYGEN__)
|
||||
#define SPC5_EDMA_ERROR_HANDLER() chSysHalt()
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief EDMA error handler IRQ priority.
|
||||
*/
|
||||
#if !defined(SPC5_EDMA_ERROR_IRQ_PRIO) || defined(__DOXYGEN__)
|
||||
#define SPC5_EDMA_ERROR_IRQ_PRIO 12
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Type of and eDMA channel number.
|
||||
*/
|
||||
typedef int32_t edma_channel_t;
|
||||
|
||||
/**
|
||||
* @brief Type of an eDMA TCD.
|
||||
*/
|
||||
typedef struct {
|
||||
union {
|
||||
uint32_t word[8];
|
||||
};
|
||||
} edma_tcd_t;
|
||||
|
||||
/**
|
||||
* @brief Type of an eDMA peripheral.
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t :14;
|
||||
vuint32_t CX :1;
|
||||
vuint32_t ECX :1;
|
||||
vuint32_t GRP3PRI :2;
|
||||
vuint32_t GRP2PRI :2;
|
||||
vuint32_t GRP1PRI :2;
|
||||
vuint32_t GRP0PRI :2;
|
||||
vuint32_t EMLM :1;
|
||||
vuint32_t CLM :1;
|
||||
vuint32_t HALT :1;
|
||||
vuint32_t HOE :1;
|
||||
vuint32_t ERGA :1;
|
||||
vuint32_t ERCA :1;
|
||||
vuint32_t EDBG :1;
|
||||
vuint32_t :1;
|
||||
} B;
|
||||
} CR; /* DMA Control Register @baseaddress + 0x0 */
|
||||
|
||||
union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t VLD :1;
|
||||
vuint32_t :14;
|
||||
vuint32_t ECX :1;
|
||||
vuint32_t GPE :1;
|
||||
vuint32_t CPE :1;
|
||||
vuint32_t ERRCHN :6;
|
||||
vuint32_t SAE :1;
|
||||
vuint32_t SOE :1;
|
||||
vuint32_t DAE :1;
|
||||
vuint32_t DOE :1;
|
||||
vuint32_t NCE :1;
|
||||
vuint32_t SGE :1;
|
||||
vuint32_t SBE :1;
|
||||
vuint32_t DBE :1;
|
||||
} B;
|
||||
} ESR; /* Error Status Register @baseaddress + 0x4 */
|
||||
|
||||
union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t ERQ63 :1;
|
||||
vuint32_t ERQ62 :1;
|
||||
vuint32_t ERQ61 :1;
|
||||
vuint32_t ERQ60 :1;
|
||||
vuint32_t ERQ59 :1;
|
||||
vuint32_t ERQ58 :1;
|
||||
vuint32_t ERQ57 :1;
|
||||
vuint32_t ERQ56 :1;
|
||||
vuint32_t ERQ55 :1;
|
||||
vuint32_t ERQ54 :1;
|
||||
vuint32_t ERQ53 :1;
|
||||
vuint32_t ERQ52 :1;
|
||||
vuint32_t ERQ51 :1;
|
||||
vuint32_t ERQ50 :1;
|
||||
vuint32_t ERQ49 :1;
|
||||
vuint32_t ERQ48 :1;
|
||||
vuint32_t ERQ47 :1;
|
||||
vuint32_t ERQ46 :1;
|
||||
vuint32_t ERQ45 :1;
|
||||
vuint32_t ERQ44 :1;
|
||||
vuint32_t ERQ43 :1;
|
||||
vuint32_t ERQ42 :1;
|
||||
vuint32_t ERQ41 :1;
|
||||
vuint32_t ERQ40 :1;
|
||||
vuint32_t ERQ39 :1;
|
||||
vuint32_t ERQ38 :1;
|
||||
vuint32_t ERQ37 :1;
|
||||
vuint32_t ERQ36 :1;
|
||||
vuint32_t ERQ35 :1;
|
||||
vuint32_t ERQ34 :1;
|
||||
vuint32_t ERQ33 :1;
|
||||
vuint32_t ERQ32 :1;
|
||||
} B;
|
||||
} ERQRH; /* DMA Enable Request Register High @baseaddress + 0x8*/
|
||||
|
||||
union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t ERQ31 :1;
|
||||
vuint32_t ERQ30 :1;
|
||||
vuint32_t ERQ29 :1;
|
||||
vuint32_t ERQ28 :1;
|
||||
vuint32_t ERQ27 :1;
|
||||
vuint32_t ERQ26 :1;
|
||||
vuint32_t ERQ25 :1;
|
||||
vuint32_t ERQ24 :1;
|
||||
vuint32_t ERQ23 :1;
|
||||
vuint32_t ERQ22 :1;
|
||||
vuint32_t ERQ21 :1;
|
||||
vuint32_t ERQ20 :1;
|
||||
vuint32_t ERQ19 :1;
|
||||
vuint32_t ERQ18 :1;
|
||||
vuint32_t ERQ17 :1;
|
||||
vuint32_t ERQ16 :1;
|
||||
vuint32_t ERQ15 :1;
|
||||
vuint32_t ERQ14 :1;
|
||||
vuint32_t ERQ13 :1;
|
||||
vuint32_t ERQ12 :1;
|
||||
vuint32_t ERQ11 :1;
|
||||
vuint32_t ERQ10 :1;
|
||||
vuint32_t ERQ09 :1;
|
||||
vuint32_t ERQ08 :1;
|
||||
vuint32_t ERQ07 :1;
|
||||
vuint32_t ERQ06 :1;
|
||||
vuint32_t ERQ05 :1;
|
||||
vuint32_t ERQ04 :1;
|
||||
vuint32_t ERQ03 :1;
|
||||
vuint32_t ERQ02 :1;
|
||||
vuint32_t ERQ01 :1;
|
||||
vuint32_t ERQ00 :1;
|
||||
} B;
|
||||
} ERQRL; /* DMA Enable Request Register Low @baseaddress + 0xC*/
|
||||
|
||||
union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
|
||||
vuint32_t EEI63 :1;
|
||||
vuint32_t EEI62 :1;
|
||||
vuint32_t EEI61 :1;
|
||||
vuint32_t EEI60 :1;
|
||||
vuint32_t EEI59 :1;
|
||||
vuint32_t EEI58 :1;
|
||||
vuint32_t EEI57 :1;
|
||||
vuint32_t EEI56 :1;
|
||||
vuint32_t EEI55 :1;
|
||||
vuint32_t EEI54 :1;
|
||||
vuint32_t EEI53 :1;
|
||||
vuint32_t EEI52 :1;
|
||||
vuint32_t EEI51 :1;
|
||||
vuint32_t EEI50 :1;
|
||||
vuint32_t EEI49 :1;
|
||||
vuint32_t EEI48 :1;
|
||||
vuint32_t EEI47 :1;
|
||||
vuint32_t EEI46 :1;
|
||||
vuint32_t EEI45 :1;
|
||||
vuint32_t EEI44 :1;
|
||||
vuint32_t EEI43 :1;
|
||||
vuint32_t EEI42 :1;
|
||||
vuint32_t EEI41 :1;
|
||||
vuint32_t EEI40 :1;
|
||||
vuint32_t EEI39 :1;
|
||||
vuint32_t EEI38 :1;
|
||||
vuint32_t EEI37 :1;
|
||||
vuint32_t EEI36 :1;
|
||||
vuint32_t EEI35 :1;
|
||||
vuint32_t EEI34 :1;
|
||||
vuint32_t EEI33 :1;
|
||||
vuint32_t EEI32 :1;
|
||||
} B;
|
||||
} EEIRH; /* DMA Enable Error Interrupt Register High @baseaddress + 0x10*/
|
||||
|
||||
union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t EEI31 :1;
|
||||
vuint32_t EEI30 :1;
|
||||
vuint32_t EEI29 :1;
|
||||
vuint32_t EEI28 :1;
|
||||
vuint32_t EEI27 :1;
|
||||
vuint32_t EEI26 :1;
|
||||
vuint32_t EEI25 :1;
|
||||
vuint32_t EEI24 :1;
|
||||
vuint32_t EEI23 :1;
|
||||
vuint32_t EEI22 :1;
|
||||
vuint32_t EEI21 :1;
|
||||
vuint32_t EEI20 :1;
|
||||
vuint32_t EEI19 :1;
|
||||
vuint32_t EEI18 :1;
|
||||
vuint32_t EEI17 :1;
|
||||
vuint32_t EEI16 :1;
|
||||
vuint32_t EEI15 :1;
|
||||
vuint32_t EEI14 :1;
|
||||
vuint32_t EEI13 :1;
|
||||
vuint32_t EEI12 :1;
|
||||
vuint32_t EEI11 :1;
|
||||
vuint32_t EEI10 :1;
|
||||
vuint32_t EEI09 :1;
|
||||
vuint32_t EEI08 :1;
|
||||
vuint32_t EEI07 :1;
|
||||
vuint32_t EEI06 :1;
|
||||
vuint32_t EEI05 :1;
|
||||
vuint32_t EEI04 :1;
|
||||
vuint32_t EEI03 :1;
|
||||
vuint32_t EEI02 :1;
|
||||
vuint32_t EEI01 :1;
|
||||
vuint32_t EEI00 :1;
|
||||
} B;
|
||||
} EEIRL; /* DMA Enable Error Interrupt Register Low @baseaddress + 0x14*/
|
||||
|
||||
union {
|
||||
vuint8_t R;
|
||||
struct {
|
||||
vuint8_t NOP :1;
|
||||
vuint8_t SERQ :7;
|
||||
} B;
|
||||
} SERQR; /* DMA Set Enable Request Register @baseaddress + 0x18*/
|
||||
|
||||
union {
|
||||
vuint8_t R;
|
||||
struct {
|
||||
vuint8_t NOP :1;
|
||||
vuint8_t CERQ :7;
|
||||
} B;
|
||||
} CERQR; /* DMA Clear Enable Request Register @baseaddress + 0x19*/
|
||||
|
||||
union {
|
||||
vuint8_t R;
|
||||
struct {
|
||||
vuint8_t NOP :1;
|
||||
vuint8_t SEEI :7;
|
||||
} B;
|
||||
} SEEIR; /* DMA Set Enable Error Interrupt Register @baseaddress + 0x1A*/
|
||||
|
||||
union {
|
||||
vuint8_t R;
|
||||
struct {
|
||||
vuint8_t NOP :1;
|
||||
vuint8_t CEEI :7;
|
||||
} B;
|
||||
} CEEIR; /* DMA Clear Enable Error Interrupt Register @baseaddress + 0x1B*/
|
||||
|
||||
union {
|
||||
vuint8_t R;
|
||||
struct {
|
||||
vuint8_t NOP :1;
|
||||
vuint8_t CINT :7;
|
||||
} B;
|
||||
} CIRQR; /* DMA Clear Interrupt Request Register @baseaddress + 0x1C */
|
||||
|
||||
union {
|
||||
vuint8_t R;
|
||||
struct {
|
||||
vuint8_t NOP :1;
|
||||
vuint8_t CERR :7;
|
||||
} B;
|
||||
} CER; /* DMA Clear error Register @baseaddress + 0x1D */
|
||||
|
||||
union {
|
||||
vuint8_t R;
|
||||
struct {
|
||||
vuint8_t NOP :1;
|
||||
vuint8_t SSB :7;
|
||||
} B;
|
||||
} SSBR; /* Set Start Bit Register @baseaddress + 0x1E */
|
||||
|
||||
union {
|
||||
vuint8_t R;
|
||||
struct {
|
||||
vuint8_t NOP :1;
|
||||
vuint8_t CDSB :7;
|
||||
} B;
|
||||
} CDSBR; /* Clear Done Status Bit Register @baseaddress + 0x1F */
|
||||
|
||||
union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t INT63 :1;
|
||||
vuint32_t INT62 :1;
|
||||
vuint32_t INT61 :1;
|
||||
vuint32_t INT60 :1;
|
||||
vuint32_t INT59 :1;
|
||||
vuint32_t INT58 :1;
|
||||
vuint32_t INT57 :1;
|
||||
vuint32_t INT56 :1;
|
||||
vuint32_t INT55 :1;
|
||||
vuint32_t INT54 :1;
|
||||
vuint32_t INT53 :1;
|
||||
vuint32_t INT52 :1;
|
||||
vuint32_t INT51 :1;
|
||||
vuint32_t INT50 :1;
|
||||
vuint32_t INT49 :1;
|
||||
vuint32_t INT48 :1;
|
||||
vuint32_t INT47 :1;
|
||||
vuint32_t INT46 :1;
|
||||
vuint32_t INT45 :1;
|
||||
vuint32_t INT44 :1;
|
||||
vuint32_t INT43 :1;
|
||||
vuint32_t INT42 :1;
|
||||
vuint32_t INT41 :1;
|
||||
vuint32_t INT40 :1;
|
||||
vuint32_t INT39 :1;
|
||||
vuint32_t INT38 :1;
|
||||
vuint32_t INT37 :1;
|
||||
vuint32_t INT36 :1;
|
||||
vuint32_t INT35 :1;
|
||||
vuint32_t INT34 :1;
|
||||
vuint32_t INT33 :1;
|
||||
vuint32_t INT32 :1;
|
||||
} B;
|
||||
} IRQRH; /* DMA Interrupt Request High @baseaddress + 0x20 */
|
||||
|
||||
union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t INT31 :1;
|
||||
vuint32_t INT30 :1;
|
||||
vuint32_t INT29 :1;
|
||||
vuint32_t INT28 :1;
|
||||
vuint32_t INT27 :1;
|
||||
vuint32_t INT26 :1;
|
||||
vuint32_t INT25 :1;
|
||||
vuint32_t INT24 :1;
|
||||
vuint32_t INT23 :1;
|
||||
vuint32_t INT22 :1;
|
||||
vuint32_t INT21 :1;
|
||||
vuint32_t INT20 :1;
|
||||
vuint32_t INT19 :1;
|
||||
vuint32_t INT18 :1;
|
||||
vuint32_t INT17 :1;
|
||||
vuint32_t INT16 :1;
|
||||
vuint32_t INT15 :1;
|
||||
vuint32_t INT14 :1;
|
||||
vuint32_t INT13 :1;
|
||||
vuint32_t INT12 :1;
|
||||
vuint32_t INT11 :1;
|
||||
vuint32_t INT10 :1;
|
||||
vuint32_t INT09 :1;
|
||||
vuint32_t INT08 :1;
|
||||
vuint32_t INT07 :1;
|
||||
vuint32_t INT06 :1;
|
||||
vuint32_t INT05 :1;
|
||||
vuint32_t INT04 :1;
|
||||
vuint32_t INT03 :1;
|
||||
vuint32_t INT02 :1;
|
||||
vuint32_t INT01 :1;
|
||||
vuint32_t INT00 :1;
|
||||
} B;
|
||||
} IRQRL; /* DMA Interrupt Request Low @baseaddress + 0x24 */
|
||||
|
||||
union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t ERR63 :1;
|
||||
vuint32_t ERR62 :1;
|
||||
vuint32_t ERR61 :1;
|
||||
vuint32_t ERR60 :1;
|
||||
vuint32_t ERR59 :1;
|
||||
vuint32_t ERR58 :1;
|
||||
vuint32_t ERR57 :1;
|
||||
vuint32_t ERR56 :1;
|
||||
vuint32_t ERR55 :1;
|
||||
vuint32_t ERR54 :1;
|
||||
vuint32_t ERR53 :1;
|
||||
vuint32_t ERR52 :1;
|
||||
vuint32_t ERR51 :1;
|
||||
vuint32_t ERR50 :1;
|
||||
vuint32_t ERR49 :1;
|
||||
vuint32_t ERR48 :1;
|
||||
vuint32_t ERR47 :1;
|
||||
vuint32_t ERR46 :1;
|
||||
vuint32_t ERR45 :1;
|
||||
vuint32_t ERR44 :1;
|
||||
vuint32_t ERR43 :1;
|
||||
vuint32_t ERR42 :1;
|
||||
vuint32_t ERR41 :1;
|
||||
vuint32_t ERR40 :1;
|
||||
vuint32_t ERR39 :1;
|
||||
vuint32_t ERR38 :1;
|
||||
vuint32_t ERR37 :1;
|
||||
vuint32_t ERR36 :1;
|
||||
vuint32_t ERR35 :1;
|
||||
vuint32_t ERR34 :1;
|
||||
vuint32_t ERR33 :1;
|
||||
vuint32_t ERR32 :1;
|
||||
} B;
|
||||
} ERH; /* DMA Error High @baseaddress + 0x28 */
|
||||
|
||||
union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t ERR31 :1;
|
||||
vuint32_t ERR30 :1;
|
||||
vuint32_t ERR29 :1;
|
||||
vuint32_t ERR28 :1;
|
||||
vuint32_t ERR27 :1;
|
||||
vuint32_t ERR26 :1;
|
||||
vuint32_t ERR25 :1;
|
||||
vuint32_t ERR24 :1;
|
||||
vuint32_t ERR23 :1;
|
||||
vuint32_t ERR22 :1;
|
||||
vuint32_t ERR21 :1;
|
||||
vuint32_t ERR20 :1;
|
||||
vuint32_t ERR19 :1;
|
||||
vuint32_t ERR18 :1;
|
||||
vuint32_t ERR17 :1;
|
||||
vuint32_t ERR16 :1;
|
||||
vuint32_t ERR15 :1;
|
||||
vuint32_t ERR14 :1;
|
||||
vuint32_t ERR13 :1;
|
||||
vuint32_t ERR12 :1;
|
||||
vuint32_t ERR11 :1;
|
||||
vuint32_t ERR10 :1;
|
||||
vuint32_t ERR09 :1;
|
||||
vuint32_t ERR08 :1;
|
||||
vuint32_t ERR07 :1;
|
||||
vuint32_t ERR06 :1;
|
||||
vuint32_t ERR05 :1;
|
||||
vuint32_t ERR04 :1;
|
||||
vuint32_t ERR03 :1;
|
||||
vuint32_t ERR02 :1;
|
||||
vuint32_t ERR01 :1;
|
||||
vuint32_t ERR00 :1;
|
||||
} B;
|
||||
} ERL; /* DMA Error Low @baseaddress + 0x2C */
|
||||
|
||||
union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t HRS63 :1;
|
||||
vuint32_t HRS62 :1;
|
||||
vuint32_t HRS61 :1;
|
||||
vuint32_t HRS60 :1;
|
||||
vuint32_t HRS59 :1;
|
||||
vuint32_t HRS58 :1;
|
||||
vuint32_t HRS57 :1;
|
||||
vuint32_t HRS56 :1;
|
||||
vuint32_t HRS55 :1;
|
||||
vuint32_t HRS54 :1;
|
||||
vuint32_t HRS53 :1;
|
||||
vuint32_t HRS52 :1;
|
||||
vuint32_t HRS51 :1;
|
||||
vuint32_t HRS50 :1;
|
||||
vuint32_t HRS49 :1;
|
||||
vuint32_t HRS48 :1;
|
||||
vuint32_t HRS47 :1;
|
||||
vuint32_t HRS46 :1;
|
||||
vuint32_t HRS45 :1;
|
||||
vuint32_t HRS44 :1;
|
||||
vuint32_t HRS43 :1;
|
||||
vuint32_t HRS42 :1;
|
||||
vuint32_t HRS41 :1;
|
||||
vuint32_t HRS40 :1;
|
||||
vuint32_t HRS39 :1;
|
||||
vuint32_t HRS38 :1;
|
||||
vuint32_t HRS37 :1;
|
||||
vuint32_t HRS36 :1;
|
||||
vuint32_t HRS35 :1;
|
||||
vuint32_t HRS34 :1;
|
||||
vuint32_t HRS33 :1;
|
||||
vuint32_t HRS32 :1;
|
||||
} B;
|
||||
} HRSH; /* hardware request status high @baseaddress + 0x30 */
|
||||
|
||||
union {
|
||||
vuint32_t R;
|
||||
struct {
|
||||
vuint32_t HRS31 :1;
|
||||
vuint32_t HRS30 :1;
|
||||
vuint32_t HRS29 :1;
|
||||
vuint32_t HRS28 :1;
|
||||
vuint32_t HRS27 :1;
|
||||
vuint32_t HRS26 :1;
|
||||
vuint32_t HRS25 :1;
|
||||
vuint32_t HRS24 :1;
|
||||
vuint32_t HRS23 :1;
|
||||
vuint32_t HRS22 :1;
|
||||
vuint32_t HRS21 :1;
|
||||
vuint32_t HRS20 :1;
|
||||
vuint32_t HRS19 :1;
|
||||
vuint32_t HRS18 :1;
|
||||
vuint32_t HRS17 :1;
|
||||
vuint32_t HRS16 :1;
|
||||
vuint32_t HRS15 :1;
|
||||
vuint32_t HRS14 :1;
|
||||
vuint32_t HRS13 :1;
|
||||
vuint32_t HRS12 :1;
|
||||
vuint32_t HRS11 :1;
|
||||
vuint32_t HRS10 :1;
|
||||
vuint32_t HRS09 :1;
|
||||
vuint32_t HRS08 :1;
|
||||
vuint32_t HRS07 :1;
|
||||
vuint32_t HRS06 :1;
|
||||
vuint32_t HRS05 :1;
|
||||
vuint32_t HRS04 :1;
|
||||
vuint32_t HRS03 :1;
|
||||
vuint32_t HRS02 :1;
|
||||
vuint32_t HRS01 :1;
|
||||
vuint32_t HRS00 :1;
|
||||
} B;
|
||||
} HRSL; /* hardware request status low @baseaddress + 0x34 */
|
||||
|
||||
uint32_t eDMA_reserved0038[50]; /* 0x0038-0x00FF */
|
||||
|
||||
union {
|
||||
vuint8_t R;
|
||||
struct {
|
||||
vuint8_t ECP :1;
|
||||
vuint8_t DPA :1;
|
||||
vuint8_t GRPPRI :2;
|
||||
vuint8_t CHPRI :4;
|
||||
} B;
|
||||
} CPR[64]; /* Channel n Priority @baseaddress + 0x100 */
|
||||
|
||||
uint32_t eDMA_reserved0140[944]; /* 0x0140-0x0FFF */
|
||||
|
||||
edma_tcd_t TCD[64];
|
||||
} edma_t;
|
||||
|
||||
/**
|
||||
* @brief DMA callback type.
|
||||
*
|
||||
* @param[in] channel the channel number
|
||||
* @param[in] p parameter for the registered function
|
||||
*/
|
||||
typedef void (*edma_callback_t)(edma_channel_t channel, void *p);
|
||||
|
||||
/**
|
||||
* @brief DMA error callback type.
|
||||
*
|
||||
* @param[in] channel the channel number
|
||||
* @param[in] p parameter for the registered function
|
||||
* @param[in] esr content of the ESR register
|
||||
*/
|
||||
typedef void (*edma_error_callback_t)(edma_channel_t channel,
|
||||
void *p,
|
||||
uint32_t esr);
|
||||
|
||||
/**
|
||||
* @brief Type of an EDMA channel configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t dma_periph; /**< @brief Peripheral to be
|
||||
associated to the channel. */
|
||||
uint8_t dma_prio; /**< @brief Priority register value
|
||||
for this channel. */
|
||||
uint8_t dma_irq_prio; /**< @brief IRQ priority level for
|
||||
this channel. */
|
||||
edma_callback_t dma_func; /**< @brief Channel callback,
|
||||
can be NULL if not required. */
|
||||
edma_error_callback_t dma_error_func; /**< @brief Channel error callback,
|
||||
can be NULL if not required. */
|
||||
void *dma_param; /**< @brief Channel callback param. */
|
||||
} edma_channel_config_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name eDMA units references
|
||||
* @{
|
||||
*/
|
||||
#if SPC5_HAS_EDMA || defined(__DOXYGEN__)
|
||||
#define SPC5_EDMA (*(edma_t *)0xFFF44000U)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Returns the TCD address associated to a channel.
|
||||
*
|
||||
* @param[in] channel the channel number
|
||||
* @return A pointer to an @p edma_tcd_t structure.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define edmaGetTCD(channel) ((edma_tcd_t *)&SPC5_EDMA.TCD[channel])
|
||||
|
||||
/**
|
||||
* @brief Sets the word 0 fields into a TCD.
|
||||
*
|
||||
* @param[in] tcdp pointer to an @p edma_tcd_t structure
|
||||
* @param[in] src the source address
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define edmaTCDSetWord0(tcdp, src) \
|
||||
((tcdp)->word[0] = (uint32_t)(src))
|
||||
|
||||
/**
|
||||
* @brief Sets the word 1 fields into a TCD.
|
||||
*
|
||||
* @param[in] tcdp pointer to an @p edma_tcd_t structure
|
||||
* @param[in] ssize the source width
|
||||
* @param[in] dst the destination width
|
||||
* @param[in] soff the source increment value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define edmaTCDSetWord1(tcdp, ssize, dsize, soff) \
|
||||
((tcdp)->word[1] = (((uint32_t)(ssize) << 24) | \
|
||||
((uint32_t)(dsize) << 16) | \
|
||||
((uint32_t)(soff) << 0)))
|
||||
|
||||
/**
|
||||
* @brief Sets the word 2 fields into a TCD.
|
||||
*
|
||||
* @param[in] tcdp pointer to an @p edma_tcd_t structure
|
||||
* @param[in] nbytes the inner counter value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define edmaTCDSetWord2(tcdp, nbytes) \
|
||||
((tcdp)->word[2] = (uint32_t)(nbytes))
|
||||
|
||||
/**
|
||||
* @brief Sets the word 3 fields into a TCD.
|
||||
*
|
||||
* @param[in] tcdp pointer to an @p edma_tcd_t structure
|
||||
* @param[in] slast the adjustment value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define edmaTCDSetWord3(tcdp, slast) \
|
||||
((tcdp)->word[3] = (uint32_t)(slast))
|
||||
|
||||
/**
|
||||
* @brief Sets the word 4 fields into a TCD.
|
||||
*
|
||||
* @param[in] tcdp pointer to an @p edma_tcd_t structure
|
||||
* @param[in] dst the destination address
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define edmaTCDSetWord4(tcdp, dst) \
|
||||
((tcdp)->word[4] = (uint32_t)(dst))
|
||||
|
||||
/**
|
||||
* @brief Sets the word 5 fields into a TCD.
|
||||
*
|
||||
* @param[in] tcdp pointer to an @p edma_tcd_t structure
|
||||
* @param[in] citer the current outer counter value
|
||||
* @param[in] doff the destination increment value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define edmaTCDSetWord5(tcdp, citer, doff) \
|
||||
((tcdp)->word[5] = (((uint32_t)(citer) << 16) | \
|
||||
((uint32_t)(doff) << 0)))
|
||||
|
||||
/**
|
||||
* @brief Sets the word 6 fields into a TCD.
|
||||
*
|
||||
* @param[in] tcdp pointer to an @p edma_tcd_t structure
|
||||
* @param[in] dlast the adjustment value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define edmaTCDSetWord6(tcdp, dlast) \
|
||||
((tcdp)->word[6] = (uint32_t)(dlast))
|
||||
|
||||
/**
|
||||
* @brief Sets the word 7 fields into a TCD.
|
||||
*
|
||||
* @param[in] tcdp pointer to an @p edma_tcd_t structure
|
||||
* @param[in] biter the base outer counter value
|
||||
* @param[in] mode the mode value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define edmaTCDSetWord7(tcdp, biter, mode) \
|
||||
((tcdp)->word[7] = (((uint32_t)(biter) << 16) | \
|
||||
((uint32_t)(mode) << 0)))
|
||||
|
||||
/**
|
||||
* @brief Starts or restarts an EDMA channel.
|
||||
*
|
||||
* @param[in] channel the channel number
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define edmaChannelStart(channel) (SPC5_EDMA.SERQR.R = (channel))
|
||||
|
||||
/**
|
||||
* @brief Stops an EDMA channel.
|
||||
*
|
||||
* @param[in] channel the channel number
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define edmaChannelStop(channel) { \
|
||||
SPC5_EDMA.CERQR.R = (channel); \
|
||||
SPC5_EDMA.CDSBR.R = (channel); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EDMA channel setup.
|
||||
*
|
||||
* @param[in] channel eDMA channel number
|
||||
* @param[in] src source address
|
||||
* @param[in] dst destination address
|
||||
* @param[in] soff source address offset
|
||||
* @param[in] doff destination address offset
|
||||
* @param[in] ssize source transfer size
|
||||
* @param[in] dsize destination transfer size
|
||||
* @param[in] nbytes minor loop count
|
||||
* @param[in] iter major loop count
|
||||
* @param[in] dlast last destination address adjustment
|
||||
* @param[in] slast last source address adjustment
|
||||
* @param[in] mode LSW of TCD register 7
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define edmaChannelSetup(channel, src, dst, soff, doff, ssize, dsize, \
|
||||
nbytes, iter, slast, dlast, mode) { \
|
||||
edma_tcd_t *tcdp = edmaGetTCD(channel); \
|
||||
edmaTCDSetWord0(tcdp, src); \
|
||||
edmaTCDSetWord1(tcdp, ssize, dsize, soff); \
|
||||
edmaTCDSetWord2(tcdp, nbytes); \
|
||||
edmaTCDSetWord3(tcdp, slast); \
|
||||
edmaTCDSetWord4(tcdp, dst); \
|
||||
edmaTCDSetWord5(tcdp, iter, doff); \
|
||||
edmaTCDSetWord6(tcdp, dlast); \
|
||||
edmaTCDSetWord7(tcdp, iter, mode); \
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void edmaInit(void);
|
||||
edma_channel_t edmaChannelAllocate(const edma_channel_config_t *ccfg);
|
||||
void edmaChannelRelease(edma_channel_t channel);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SPC5_HAS_EDMA */
|
||||
|
||||
#endif /* _SPC5_EDMA_H_ */
|
||||
|
||||
/** @} */
|
||||
+744
@@ -0,0 +1,744 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 SPC5xx/EQADC_v1/adc_lld.c
|
||||
* @brief SPC5xx low level ADC driver code.
|
||||
*
|
||||
* @addtogroup ADC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_ADC || defined(__DOXYGEN__)
|
||||
|
||||
/* Some forward declarations.*/
|
||||
static void adc_serve_rfifo_irq(edma_channel_t channel, void *p);
|
||||
static void adc_serve_dma_error_irq(edma_channel_t channel,
|
||||
void *p,
|
||||
uint32_t esr);
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Calibration constant.
|
||||
* @details Ideal conversion result for 75%(VRH - VRL) minus 2.
|
||||
*/
|
||||
#define ADC_IDEAL_RES75_2 12286
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief ADCD1 driver identifier.
|
||||
*/
|
||||
#if SPC5_ADC_USE_ADC0_Q0 || defined(__DOXYGEN__)
|
||||
ADCDriver ADCD1;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADCD2 driver identifier.
|
||||
*/
|
||||
#if SPC5_ADC_USE_ADC0_Q1 || defined(__DOXYGEN__)
|
||||
ADCDriver ADCD2;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADCD3 driver identifier.
|
||||
*/
|
||||
#if SPC5_ADC_USE_ADC0_Q2 || defined(__DOXYGEN__)
|
||||
ADCDriver ADCD3;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADCD4 driver identifier.
|
||||
*/
|
||||
#if SPC5_ADC_USE_ADC1_Q3 || defined(__DOXYGEN__)
|
||||
ADCDriver ADCD4;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADCD5 driver identifier.
|
||||
*/
|
||||
#if SPC5_ADC_USE_ADC1_Q4 || defined(__DOXYGEN__)
|
||||
ADCDriver ADCD5;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADCD6 driver identifier.
|
||||
*/
|
||||
#if SPC5_ADC_USE_ADC1_Q5 || defined(__DOXYGEN__)
|
||||
ADCDriver ADCD6;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Number of active ADC FIFOs.
|
||||
*/
|
||||
static uint32_t adc_active_fifos;
|
||||
|
||||
/**
|
||||
* @brief Static setup for input resistors.
|
||||
*/
|
||||
static const uint16_t pudcrs[8] = SPC5_ADC_PUDCR;
|
||||
|
||||
#if SPC5_ADC_USE_ADC0_Q0 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief DMA configuration for EQADC CFIFO0.
|
||||
*/
|
||||
static const edma_channel_config_t adc_cfifo0_dma_config = {
|
||||
0, SPC5_ADC_FIFO0_DMA_PRIO, SPC5_ADC_FIFO0_DMA_IRQ_PRIO,
|
||||
NULL, adc_serve_dma_error_irq, &ADCD1
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief DMA configuration for EQADC RFIFO0.
|
||||
*/
|
||||
static const edma_channel_config_t adc_rfifo0_dma_config = {
|
||||
1, SPC5_ADC_FIFO0_DMA_PRIO, SPC5_ADC_FIFO0_DMA_IRQ_PRIO,
|
||||
adc_serve_rfifo_irq, adc_serve_dma_error_irq, &ADCD1
|
||||
};
|
||||
#endif /* SPC5_ADC_USE_ADC0_Q0 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC0_Q1 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief DMA configuration for EQADC CFIFO1.
|
||||
*/
|
||||
static const edma_channel_config_t adc_cfifo1_dma_config = {
|
||||
2, SPC5_ADC_FIFO1_DMA_PRIO, SPC5_ADC_FIFO1_DMA_IRQ_PRIO,
|
||||
NULL, adc_serve_dma_error_irq, &ADCD2
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief DMA configuration for EQADC RFIFO1.
|
||||
*/
|
||||
static const edma_channel_config_t adc_rfifo1_dma_config = {
|
||||
3, SPC5_ADC_FIFO1_DMA_PRIO, SPC5_ADC_FIFO1_DMA_IRQ_PRIO,
|
||||
adc_serve_rfifo_irq, adc_serve_dma_error_irq, &ADCD2
|
||||
};
|
||||
#endif /* SPC5_ADC_USE_ADC0_Q1 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC0_Q2 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief DMA configuration for EQADC CFIFO2.
|
||||
*/
|
||||
static const edma_channel_config_t adc_cfifo2_dma_config = {
|
||||
4, SPC5_ADC_FIFO2_DMA_PRIO, SPC5_ADC_FIFO2_DMA_IRQ_PRIO,
|
||||
NULL, adc_serve_dma_error_irq, &ADCD3
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief DMA configuration for EQADC RFIFO2.
|
||||
*/
|
||||
static const edma_channel_config_t adc_rfifo2_dma_config = {
|
||||
5, SPC5_ADC_FIFO2_DMA_PRIO, SPC5_ADC_FIFO2_DMA_IRQ_PRIO,
|
||||
adc_serve_rfifo_irq, adc_serve_dma_error_irq, &ADCD3
|
||||
};
|
||||
#endif /* SPC5_ADC_USE_ADC0_Q2 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC1_Q3 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief DMA configuration for EQADC CFIFO3.
|
||||
*/
|
||||
static const edma_channel_config_t adc_cfifo3_dma_config = {
|
||||
6, SPC5_ADC_FIFO3_DMA_PRIO, SPC5_ADC_FIFO3_DMA_IRQ_PRIO,
|
||||
NULL, adc_serve_dma_error_irq, &ADCD4
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief DMA configuration for EQADC RFIFO3.
|
||||
*/
|
||||
static const edma_channel_config_t adc_rfifo3_dma_config = {
|
||||
7, SPC5_ADC_FIFO3_DMA_PRIO, SPC5_ADC_FIFO3_DMA_IRQ_PRIO,
|
||||
adc_serve_rfifo_irq, adc_serve_dma_error_irq, &ADCD4
|
||||
};
|
||||
#endif /* SPC5_ADC_USE_ADC1_Q3 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC1_Q4 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief DMA configuration for EQADC CFIFO4.
|
||||
*/
|
||||
static const edma_channel_config_t adc_cfifo4_dma_config = {
|
||||
8, SPC5_ADC_FIFO4_DMA_PRIO, SPC5_ADC_FIFO4_DMA_IRQ_PRIO,
|
||||
NULL, adc_serve_dma_error_irq, &ADCD5
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief DMA configuration for EQADC RFIFO4.
|
||||
*/
|
||||
static const edma_channel_config_t adc_rfifo4_dma_config = {
|
||||
9, SPC5_ADC_FIFO4_DMA_PRIO, SPC5_ADC_FIFO4_DMA_IRQ_PRIO,
|
||||
adc_serve_rfifo_irq, adc_serve_dma_error_irq, &ADCD5
|
||||
};
|
||||
#endif /* SPC5_ADC_USE_ADC1_Q4 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC1_Q5 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief DMA configuration for EQADC CFIFO5.
|
||||
*/
|
||||
static const edma_channel_config_t adc_cfifo5_dma_config = {
|
||||
10, SPC5_ADC_FIFO5_DMA_PRIO, SPC5_ADC_FIFO5_DMA_IRQ_PRIO,
|
||||
NULL, adc_serve_dma_error_irq, &ADCD6
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief DMA configuration for EQADC RFIFO5.
|
||||
*/
|
||||
static const edma_channel_config_t adc_rfifo5_dma_config = {
|
||||
11, SPC5_ADC_FIFO5_DMA_PRIO, SPC5_ADC_FIFO5_DMA_IRQ_PRIO,
|
||||
adc_serve_rfifo_irq, adc_serve_dma_error_irq, &ADCD6
|
||||
};
|
||||
#endif /* SPC5_ADC_USE_ADC1_Q5 */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions and macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Unsigned two's complement.
|
||||
*
|
||||
* @param[in] n the value to be complemented
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define CPL2(n) ((~(uint32_t)(n)) + 1)
|
||||
|
||||
/**
|
||||
* @brief Address of a CFIFO push register.
|
||||
*
|
||||
* @param[in] fifo the FIFO identifier
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define CFIFO_PUSH_ADDR(fifo) ((uint32_t *)(&EQADC.CFPR[fifo].R))
|
||||
|
||||
/**
|
||||
* @brief Address of a RFIFO pop register.
|
||||
*
|
||||
* @param[in] fifo the FIFO identifier
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define RFIFO_POP_ADDR(fifo) (((uint16_t *)&EQADC.RFPR[fifo].R) + 1)
|
||||
|
||||
/**
|
||||
* @brief Enables a CFIFO.
|
||||
*
|
||||
* @param[in] fifo the FIFO identifier
|
||||
* @param[in] cfcr CFCR register value
|
||||
* @param[in] idcr IDCR register value
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void cfifo_enable(adcfifo_t fifo, uint16_t cfcr, uint16_t idcr) {
|
||||
|
||||
EQADC.CFCR[fifo].R = cfcr;
|
||||
EQADC.IDCR[fifo].R = idcr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables a CFIFO and the associated resources.
|
||||
*
|
||||
* @param[in] fifo the FIFO identifier
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void cfifo_disable(adcfifo_t fifo) {
|
||||
|
||||
/* Disables the CFIFO.*/
|
||||
EQADC.CFCR[fifo].R = EQADC_CFCR_MODE_DISABLED;
|
||||
|
||||
/* Disables Interrupts and DMAs of the CFIFO.*/
|
||||
EQADC.IDCR[fifo].R = 0;
|
||||
|
||||
/* Waits for the CFIFO to become idle.*/
|
||||
while ((EQADC.CFSR.R & (0xC0000000 >> (fifo * 2))) != 0)
|
||||
;
|
||||
|
||||
/* Invalidates the CFIFO.*/
|
||||
EQADC.CFCR[fifo].R = EQADC_CFCR_CFINV | EQADC_CFCR_MODE_DISABLED;
|
||||
|
||||
/* Clears all Interrupts and eDMA flags for the CFIFO.*/
|
||||
EQADC.FISR[fifo].R = EQADC_FISR_CLEAR_MASK;
|
||||
|
||||
/* Clears the Tx Count Registers for the CFIFO.*/
|
||||
EQADC.CFTCR[fifo].R = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pushes a command into the CFIFO0.
|
||||
*
|
||||
* @param[in] cmd the command
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void cfifo0_push_command(adccommand_t cmd) {
|
||||
|
||||
while (EQADC.FISR[0].B.CFCTR >= 4)
|
||||
;
|
||||
EQADC.CFPR[0].R = cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Waits until the RFIFO0 contains the specified number of entries.
|
||||
*
|
||||
* @param[in] n number of entries
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void cfifo0_wait_rfifo(uint32_t n) {
|
||||
|
||||
while (EQADC.FISR[0].B.RFCTR < n)
|
||||
;
|
||||
EQADC.FISR[0].R = EQADC_FISR_CLEAR_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads a sample from the RFIFO0.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define rfifo0_get_value() (EQADC.RFPR[0].R)
|
||||
|
||||
/**
|
||||
* @brief Writes an internal ADC register.
|
||||
*
|
||||
* @param[in] adc the ADC unit
|
||||
* @param[in] reg the register index
|
||||
* @param[in] value value to be written into the register
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define adc_write_register(adc, reg, value) \
|
||||
cfifo0_push_command(EQADC_RW_WRITE | (adc) | EQADC_RW_REG_ADDR(reg) | \
|
||||
EQADC_RW_VALUE(value))
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enables both ADCs.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void adc_enable(void) {
|
||||
|
||||
/* Both ADCs must be enabled because this sentence in the reference manual:
|
||||
"Both ADC0 and ADC1 of an eQADC module pair must be enabled before
|
||||
calibrating or using either ADC0 or ADC1 of the pair. Failure to
|
||||
enable both ADC0 and ADC1 of the pair can result in inaccurate
|
||||
conversions.".*/
|
||||
adc_write_register(EQADC_RW_BN_ADC0, ADC_REG_CR,
|
||||
SPC5_ADC_CR_CLK_PS | ADC_CR_EN);
|
||||
adc_write_register(EQADC_RW_BN_ADC1, ADC_REG_CR,
|
||||
SPC5_ADC_CR_CLK_PS | ADC_CR_EN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables both ADCs.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void adc_disable(void) {
|
||||
|
||||
adc_write_register(EQADC_RW_BN_ADC0, ADC_REG_CR,
|
||||
SPC5_ADC_CR_CLK_PS);
|
||||
adc_write_register(EQADC_RW_BN_ADC1, ADC_REG_CR,
|
||||
SPC5_ADC_CR_CLK_PS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calibrates an ADC unit.
|
||||
*
|
||||
* @param[in] adc the ADC unit
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void adc_calibrate(uint32_t adc) {
|
||||
uint16_t res25, res75;
|
||||
uint32_t gcc, occ;
|
||||
|
||||
/* Starts the calibration, write command messages to sample 25% and
|
||||
75% VREF.*/
|
||||
cfifo0_push_command(0x00002C00 | adc); /* Vref 25%.*/
|
||||
cfifo0_push_command(0x00002B00 | adc); /* Vref 75%.*/
|
||||
cfifo0_wait_rfifo(2);
|
||||
|
||||
/* Reads the results and compute calibration register values.*/
|
||||
res25 = rfifo0_get_value();
|
||||
res75 = rfifo0_get_value();
|
||||
|
||||
gcc = 0x08000000UL / ((uint32_t)res75 - (uint32_t)res25);
|
||||
occ = (uint32_t)ADC_IDEAL_RES75_2 - ((gcc * (uint32_t)res75) >> 14);
|
||||
|
||||
/* Loads the gain and offset values (default configuration, 12 bits).*/
|
||||
adc_write_register(adc, ADC_REG_GCCR, gcc);
|
||||
adc_write_register(adc, ADC_REG_OCCR, occ & 0xFFFF);
|
||||
|
||||
/* Loads gain and offset values (alternate configuration 1, 10 bits).*/
|
||||
adc_write_register(adc, ADC_REG_AC1GCCR, gcc);
|
||||
adc_write_register(adc, ADC_REG_AC1OCCR, occ & 0xFFFF);
|
||||
|
||||
/* Loads gain and offset values (alternate configuration 1, 8 bits).*/
|
||||
adc_write_register(adc, ADC_REG_AC2GCCR, gcc);
|
||||
adc_write_register(adc, ADC_REG_AC2OCCR, occ & 0xFFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calibrates an ADC unit.
|
||||
*
|
||||
* @param[in] adc the ADC unit
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void adc_setup_resistors(uint32_t adc) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
adc_write_register(adc, ADC_REG_PUDCR(i), pudcrs[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shared ISR for RFIFO DMA events.
|
||||
*
|
||||
* @param[in] channel the channel number
|
||||
* @param[in] p parameter for the registered function
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void adc_serve_rfifo_irq(edma_channel_t channel, void *p) {
|
||||
ADCDriver *adcp = (ADCDriver *)p;
|
||||
edma_tcd_t *tcdp = edmaGetTCD(channel);
|
||||
|
||||
if (adcp->grpp != NULL) {
|
||||
if ((tcdp->word[5] >> 16) != (tcdp->word[7] >> 16)) {
|
||||
/* Half transfer processing.*/
|
||||
_adc_isr_half_code(adcp);
|
||||
}
|
||||
else {
|
||||
/* Re-starting DMA channels if in circular mode.*/
|
||||
if (adcp->grpp->circular) {
|
||||
edmaChannelStart(adcp->rfifo_channel);
|
||||
edmaChannelStart(adcp->cfifo_channel);
|
||||
}
|
||||
|
||||
/* Transfer complete processing.*/
|
||||
_adc_isr_full_code(adcp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shared ISR for CFIFO/RFIFO DMA error events.
|
||||
*
|
||||
* @param[in] channel the channel number
|
||||
* @param[in] p parameter for the registered function
|
||||
* @param[in] esr content of the ESR register
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void adc_serve_dma_error_irq(edma_channel_t channel,
|
||||
void *p,
|
||||
uint32_t esr) {
|
||||
ADCDriver *adcp = (ADCDriver *)p;
|
||||
|
||||
(void)channel;
|
||||
(void)esr;
|
||||
|
||||
_adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE);
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level ADC driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_init(void) {
|
||||
|
||||
/* FIFOs initially all not in use.*/
|
||||
adc_active_fifos = 0;
|
||||
|
||||
#if SPC5_ADC_USE_ADC0_Q0
|
||||
/* Driver initialization.*/
|
||||
adcObjectInit(&ADCD1);
|
||||
ADCD1.cfifo_channel = EDMA_ERROR;
|
||||
ADCD1.rfifo_channel = EDMA_ERROR;
|
||||
ADCD1.fifo = ADC_FIFO_0;
|
||||
#endif /* SPC5_ADC_USE_EQADC_Q0 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC0_Q1
|
||||
/* Driver initialization.*/
|
||||
adcObjectInit(&ADCD2);
|
||||
ADCD2.cfifo_channel = EDMA_ERROR;
|
||||
ADCD2.rfifo_channel = EDMA_ERROR;
|
||||
ADCD2.fifo = ADC_FIFO_1;
|
||||
#endif /* SPC5_ADC_USE_EQADC_Q1 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC0_Q2
|
||||
/* Driver initialization.*/
|
||||
adcObjectInit(&ADCD3);
|
||||
ADCD3.cfifo_channel = EDMA_ERROR;
|
||||
ADCD3.rfifo_channel = EDMA_ERROR;
|
||||
ADCD3.fifo = ADC_FIFO_2;
|
||||
#endif /* SPC5_ADC_USE_EQADC_Q2 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC1_Q3
|
||||
/* Driver initialization.*/
|
||||
adcObjectInit(&ADCD4);
|
||||
ADCD4.cfifo_channel = EDMA_ERROR;
|
||||
ADCD4.rfifo_channel = EDMA_ERROR;
|
||||
ADCD4.fifo = ADC_FIFO_3;
|
||||
#endif /* SPC5_ADC_USE_ADC1_Q3 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC1_Q4
|
||||
/* Driver initialization.*/
|
||||
adcObjectInit(&ADCD5);
|
||||
ADCD5.cfifo_channel = EDMA_ERROR;
|
||||
ADCD5.rfifo_channel = EDMA_ERROR;
|
||||
ADCD5.fifo = ADC_FIFO_4;
|
||||
#endif /* SPC5_ADC_USE_ADC1_Q4 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC1_Q5
|
||||
/* Driver initialization.*/
|
||||
adcObjectInit(&ADCD6);
|
||||
ADCD6.cfifo_channel = EDMA_ERROR;
|
||||
ADCD6.rfifo_channel = EDMA_ERROR;
|
||||
ADCD6.fifo = ADC_FIFO_5;
|
||||
#endif /* SPC5_ADC_USE_ADC1_Q5 */
|
||||
|
||||
/* Temporarily enables CFIFO0 for calibration and initialization.*/
|
||||
cfifo_enable(ADC_FIFO_0, EQADC_CFCR_SSE | EQADC_CFCR_MODE_SWCS, 0);
|
||||
adc_enable();
|
||||
|
||||
/* Calibration of both ADC units, programming alternate configs
|
||||
one and two for 10 and 8 bits operations, setting up pull up/down
|
||||
resistors.*/
|
||||
#if SPC5_ADC_USE_ADC0
|
||||
adc_calibrate(EQADC_RW_BN_ADC0);
|
||||
adc_write_register(EQADC_RW_BN_ADC0, ADC_REG_AC1CR, ADC_ACR_RESSEL_10BITS);
|
||||
adc_write_register(EQADC_RW_BN_ADC0, ADC_REG_AC2CR, ADC_ACR_RESSEL_8BITS);
|
||||
adc_setup_resistors(EQADC_RW_BN_ADC0);
|
||||
#endif
|
||||
#if SPC5_ADC_USE_ADC1
|
||||
adc_calibrate(EQADC_RW_BN_ADC1);
|
||||
adc_write_register(EQADC_RW_BN_ADC1, ADC_REG_AC1CR, ADC_ACR_RESSEL_10BITS);
|
||||
adc_write_register(EQADC_RW_BN_ADC1, ADC_REG_AC2CR, ADC_ACR_RESSEL_8BITS);
|
||||
adc_setup_resistors(EQADC_RW_BN_ADC1);
|
||||
#endif
|
||||
|
||||
/* ADCs disabled until the driver is started by the application.*/
|
||||
adc_disable();
|
||||
cfifo_disable(ADC_FIFO_0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the ADC peripheral.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_start(ADCDriver *adcp) {
|
||||
|
||||
chDbgAssert(adc_active_fifos < 6, "adc_lld_start(), #1", "too many FIFOs");
|
||||
|
||||
if (adcp->state == ADC_STOP) {
|
||||
/* Enables the peripheral.*/
|
||||
#if SPC5_ADC_USE_ADC0_Q0
|
||||
if (&ADCD1 == adcp) {
|
||||
adcp->cfifo_channel = edmaChannelAllocate(&adc_cfifo0_dma_config);
|
||||
adcp->rfifo_channel = edmaChannelAllocate(&adc_rfifo0_dma_config);
|
||||
adc_active_fifos++;
|
||||
}
|
||||
#endif /* SPC5_ADC_USE_ADC0_Q0 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC0_Q1
|
||||
if (&ADCD2 == adcp) {
|
||||
adcp->cfifo_channel = edmaChannelAllocate(&adc_cfifo1_dma_config);
|
||||
adcp->rfifo_channel = edmaChannelAllocate(&adc_rfifo1_dma_config);
|
||||
adc_active_fifos++;
|
||||
}
|
||||
#endif /* SPC5_ADC_USE_ADC0_Q1 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC0_Q2
|
||||
if (&ADCD3 == adcp) {
|
||||
adcp->cfifo_channel = edmaChannelAllocate(&adc_cfifo2_dma_config);
|
||||
adcp->rfifo_channel = edmaChannelAllocate(&adc_rfifo2_dma_config);
|
||||
adc_active_fifos++;
|
||||
}
|
||||
#endif /* SPC5_ADC_USE_ADC0_Q2 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC1_Q3
|
||||
if (&ADCD4 == adcp) {
|
||||
adcp->cfifo_channel = edmaChannelAllocate(&adc_cfifo3_dma_config);
|
||||
adcp->rfifo_channel = edmaChannelAllocate(&adc_rfifo3_dma_config);
|
||||
adc_active_fifos++;
|
||||
}
|
||||
#endif /* SPC5_ADC_USE_ADC1_Q3 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC1_Q4
|
||||
if (&ADCD5 == adcp) {
|
||||
adcp->cfifo_channel = edmaChannelAllocate(&adc_cfifo4_dma_config);
|
||||
adcp->rfifo_channel = edmaChannelAllocate(&adc_rfifo4_dma_config);
|
||||
adc_active_fifos++;
|
||||
}
|
||||
#endif /* SPC5_ADC_USE_ADC1_Q4 */
|
||||
|
||||
#if SPC5_ADC_USE_ADC1_Q5
|
||||
if (&ADCD6 == adcp) {
|
||||
adcp->cfifo_channel = edmaChannelAllocate(&adc_cfifo5_dma_config);
|
||||
adcp->rfifo_channel = edmaChannelAllocate(&adc_rfifo5_dma_config);
|
||||
adc_active_fifos++;
|
||||
}
|
||||
#endif /* SPC5_ADC_USE_ADC1_Q5 */
|
||||
|
||||
/* If this is the first FIFO activated then the ADC is enabled.*/
|
||||
if (adc_active_fifos == 1)
|
||||
adc_enable();
|
||||
}
|
||||
|
||||
chDbgAssert((adcp->cfifo_channel != EDMA_ERROR) &&
|
||||
(adcp->rfifo_channel != EDMA_ERROR),
|
||||
"adc_lld_start(), #2", "channel cannot be allocated");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the ADC peripheral.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_stop(ADCDriver *adcp) {
|
||||
|
||||
chDbgAssert(adc_active_fifos < 6, "adc_lld_stop(), #1", "too many FIFOs");
|
||||
|
||||
if (adcp->state == ADC_READY) {
|
||||
/* Resets the peripheral.*/
|
||||
|
||||
/* Releases the allocated EDMA channels.*/
|
||||
edmaChannelRelease(adcp->cfifo_channel);
|
||||
edmaChannelRelease(adcp->rfifo_channel);
|
||||
|
||||
/* If it is the last active FIFO then the ADC is disable too.*/
|
||||
if (--adc_active_fifos == 0)
|
||||
adc_disable();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts an ADC conversion.
|
||||
* @note Because an HW constraint the number of rows in the samples
|
||||
* array must not be greater than the preconfigured value in
|
||||
* the conversion group.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_start_conversion(ADCDriver *adcp) {
|
||||
uint32_t bitoff;
|
||||
|
||||
chDbgAssert(adcp->grpp->num_iterations >= adcp->depth,
|
||||
"adc_lld_start_conversion(), #1", "too many elements");
|
||||
|
||||
/* Setting up CFIFO TCD parameters.*/
|
||||
edmaChannelSetup(adcp->cfifo_channel, /* channel. */
|
||||
adcp->grpp->commands, /* src. */
|
||||
CFIFO_PUSH_ADDR(adcp->fifo), /* dst. */
|
||||
4, /* soff, advance by 4. */
|
||||
0, /* doff, do not advance. */
|
||||
2, /* ssize, 32 bits transfers.*/
|
||||
2, /* dsize, 32 bits transfers.*/
|
||||
4, /* nbytes, always four. */
|
||||
(uint32_t)adcp->grpp->num_channels *
|
||||
(uint32_t)adcp->depth, /* iter. */
|
||||
CPL2((uint32_t)adcp->grpp->num_channels *
|
||||
(uint32_t)adcp->depth *
|
||||
sizeof(adccommand_t)), /* slast. */
|
||||
0, /* dlast, no dest.adjust. */
|
||||
EDMA_TCD_MODE_DREQ); /* mode. */
|
||||
|
||||
/* Setting up RFIFO TCD parameters.*/
|
||||
edmaChannelSetup(adcp->rfifo_channel, /* channel. */
|
||||
RFIFO_POP_ADDR(adcp->fifo), /* src. */
|
||||
adcp->samples, /* dst. */
|
||||
0, /* soff, do not advance. */
|
||||
2, /* doff, advance by two. */
|
||||
1, /* ssize, 16 bits transfers.*/
|
||||
1, /* dsize, 16 bits transfers.*/
|
||||
2, /* nbytes, always two. */
|
||||
(uint32_t)adcp->grpp->num_channels *
|
||||
(uint32_t)adcp->depth, /* iter. */
|
||||
0, /* slast, no source adjust. */
|
||||
CPL2((uint32_t)adcp->grpp->num_channels *
|
||||
(uint32_t)adcp->depth *
|
||||
sizeof(adcsample_t)), /* dlast. */
|
||||
EDMA_TCD_MODE_DREQ | EDMA_TCD_MODE_INT_END |
|
||||
((adcp->depth > 1) ? EDMA_TCD_MODE_INT_HALF: 0));/* mode.*/
|
||||
|
||||
/* HW triggers setup.*/
|
||||
bitoff = 20 + ((uint32_t)adcp->fifo * 2);
|
||||
SIU.ETISR.R = (SIU.ETISR.R & ~(3U << bitoff)) |
|
||||
(adcp->grpp->tsel << bitoff);
|
||||
bitoff = (uint32_t)adcp->fifo * 5;
|
||||
SIU.ISEL3.R = (SIU.ISEL3.R & ~(31U << bitoff)) |
|
||||
(adcp->grpp->etsel << bitoff);
|
||||
|
||||
/* Starting DMA channels.*/
|
||||
edmaChannelStart(adcp->rfifo_channel);
|
||||
edmaChannelStart(adcp->cfifo_channel);
|
||||
|
||||
/* Enabling CFIFO, conversion starts.*/
|
||||
cfifo_enable(adcp->fifo, adcp->grpp->cfcr,
|
||||
EQADC_IDCR_CFFE | EQADC_IDCR_CFFS |
|
||||
EQADC_IDCR_RFDE | EQADC_IDCR_RFDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops an ongoing conversion.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_stop_conversion(ADCDriver *adcp) {
|
||||
|
||||
/* Stopping DMA channels.*/
|
||||
edmaChannelStop(adcp->cfifo_channel);
|
||||
edmaChannelStop(adcp->rfifo_channel);
|
||||
|
||||
/* Disabling CFIFO.*/
|
||||
cfifo_disable(adcp->fifo);
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_ADC */
|
||||
|
||||
/** @} */
|
||||
+705
@@ -0,0 +1,705 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 SPC5xx/EQADC_v1/adc_lld.c
|
||||
* @brief SPC5xx low level ADC driver header.
|
||||
*
|
||||
* @addtogroup ADC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _ADC_LLD_H_
|
||||
#define _ADC_LLD_H_
|
||||
|
||||
#if HAL_USE_ADC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Analog channel identifiers
|
||||
* @{
|
||||
*/
|
||||
#define ADC_CHN_AN0 0U
|
||||
#define ADC_CHN_AN1 1U
|
||||
#define ADC_CHN_AN2 2U
|
||||
#define ADC_CHN_AN3 3U
|
||||
#define ADC_CHN_AN4 4U
|
||||
#define ADC_CHN_AN5 5U
|
||||
#define ADC_CHN_AN6 6U
|
||||
#define ADC_CHN_AN7 7U
|
||||
#define ADC_CHN_AN8 8U
|
||||
#define ADC_CHN_AN9 9U
|
||||
#define ADC_CHN_AN10 10U
|
||||
#define ADC_CHN_AN11 11U
|
||||
#define ADC_CHN_AN12 12U
|
||||
#define ADC_CHN_AN13 13U
|
||||
#define ADC_CHN_AN14 14U
|
||||
#define ADC_CHN_AN15 15U
|
||||
#define ADC_CHN_AN16 16U
|
||||
#define ADC_CHN_AN17 17U
|
||||
#define ADC_CHN_AN18 18U
|
||||
#define ADC_CHN_AN19 19U
|
||||
#define ADC_CHN_AN20 20U
|
||||
#define ADC_CHN_AN21 21U
|
||||
#define ADC_CHN_AN22 22U
|
||||
#define ADC_CHN_AN23 23U
|
||||
#define ADC_CHN_AN24 24U
|
||||
#define ADC_CHN_AN25 25U
|
||||
#define ADC_CHN_AN26 26U
|
||||
#define ADC_CHN_AN27 27U
|
||||
#define ADC_CHN_AN28 28U
|
||||
#define ADC_CHN_AN29 29U
|
||||
#define ADC_CHN_AN30 30U
|
||||
#define ADC_CHN_AN31 31U
|
||||
#define ADC_CHN_AN32 32U
|
||||
#define ADC_CHN_AN33 33U
|
||||
#define ADC_CHN_AN34 34U
|
||||
#define ADC_CHN_AN35 35U
|
||||
#define ADC_CHN_AN36 36U
|
||||
#define ADC_CHN_AN37 37U
|
||||
#define ADC_CHN_AN38 38U
|
||||
#define ADC_CHN_AN39 39U
|
||||
#define ADC_CHN_VRH 40U
|
||||
#define ADC_CHN_VRL 41U
|
||||
#define ADC_CHN_VREF50 42U
|
||||
#define ADC_CHN_VREF75 43U
|
||||
#define ADC_CHN_VREF25 44U
|
||||
#define ADC_CHN_BANDGAP 45U
|
||||
#define ADC_CHN_DAN0 96U
|
||||
#define ADC_CHN_DAN1 97U
|
||||
#define ADC_CHN_DAN2 98U
|
||||
#define ADC_CHN_DAN3 99U
|
||||
#define ADC_CHN_TEMP_SENSOR 128U
|
||||
#define ADC_CHN_SPARE 129U
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Internal registers indexes
|
||||
* @{
|
||||
*/
|
||||
#define ADC_REG_CR 0x1
|
||||
#define ADC_REG_TSCR 0x2
|
||||
#define ADC_REG_TBCR 0x3
|
||||
#define ADC_REG_GCCR 0x4
|
||||
#define ADC_REG_OCCR 0x5
|
||||
#define ADC_REG_AC1GCCR 0x31
|
||||
#define ADC_REG_AC1OCCR 0x32
|
||||
#define ADC_REG_AC2GCCR 0x35
|
||||
#define ADC_REG_AC2OCCR 0x36
|
||||
#define ADC_REG_AC1CR 0x30
|
||||
#define ADC_REG_AC2CR 0x34
|
||||
#define ADC_REG_AC3CR 0x38
|
||||
#define ADC_REG_AC4CR 0x3C
|
||||
#define ADC_REG_AC5CR 0x40
|
||||
#define ADC_REG_AC6CR 0x44
|
||||
#define ADC_REG_AC7CR 0x48
|
||||
#define ADC_REG_AC8CR 0x4C
|
||||
#define ADC_REG_PUDCR(n) (0x70 + (n))
|
||||
#define ADC_REG_PUDCR0 0x70UL
|
||||
#define ADC_REG_PUDCR1 0x71UL
|
||||
#define ADC_REG_PUDCR2 0x72UL
|
||||
#define ADC_REG_PUDCR3 0x73UL
|
||||
#define ADC_REG_PUDCR4 0x74UL
|
||||
#define ADC_REG_PUDCR5 0x75UL
|
||||
#define ADC_REG_PUDCR6 0x76UL
|
||||
#define ADC_REG_PUDCR7 0x77UL
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name EQADC IDCR registers definitions
|
||||
* @{
|
||||
*/
|
||||
#define EQADC_IDCR_NCIE (1U << 15)
|
||||
#define EQADC_IDCR_TORIE (1U << 14)
|
||||
#define EQADC_IDCR_PIE (1U << 13)
|
||||
#define EQADC_IDCR_EOQIE (1U << 12)
|
||||
#define EQADC_IDCR_CFUIE (1U << 11)
|
||||
#define EQADC_IDCR_CFFE (1U << 9)
|
||||
#define EQADC_IDCR_CFFS (1U << 8)
|
||||
#define EQADC_IDCR_RFOIE (1U << 3)
|
||||
#define EQADC_IDCR_RFDE (1U << 1)
|
||||
#define EQADC_IDCR_RFDS (1U << 0)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name EQADC CFCR registers definitions
|
||||
* @{
|
||||
*/
|
||||
#define EQADC_CFCR_CFEEE0 (1U << 12)
|
||||
#define EQADC_CFCR_STRME0 (1U << 11)
|
||||
#define EQADC_CFCR_SSE (1U << 10)
|
||||
#define EQADC_CFCR_CFINV (1U << 9)
|
||||
#define EQADC_CFCR_MODE_MASK (15U << 4)
|
||||
#define EQADC_CFCR_MODE(n) ((n) << 4)
|
||||
#define EQADC_CFCR_MODE_DISABLED EQADC_CFCR_MODE(0)
|
||||
#define EQADC_CFCR_MODE_SWSS EQADC_CFCR_MODE(1)
|
||||
#define EQADC_CFCR_MODE_HWSS_LL EQADC_CFCR_MODE(2)
|
||||
#define EQADC_CFCR_MODE_HWSS_HL EQADC_CFCR_MODE(3)
|
||||
#define EQADC_CFCR_MODE_HWSS_FE EQADC_CFCR_MODE(4)
|
||||
#define EQADC_CFCR_MODE_HWSS_RE EQADC_CFCR_MODE(5)
|
||||
#define EQADC_CFCR_MODE_HWSS_BE EQADC_CFCR_MODE(6)
|
||||
#define EQADC_CFCR_MODE_SWCS EQADC_CFCR_MODE(9)
|
||||
#define EQADC_CFCR_MODE_HWCS_LL EQADC_CFCR_MODE(10)
|
||||
#define EQADC_CFCR_MODE_HWCS_HL EQADC_CFCR_MODE(11)
|
||||
#define EQADC_CFCR_MODE_HWCS_FE EQADC_CFCR_MODE(12)
|
||||
#define EQADC_CFCR_MODE_HWCS_RE EQADC_CFCR_MODE(13)
|
||||
#define EQADC_CFCR_MODE_HWCS_BE EQADC_CFCR_MODE(14)
|
||||
#define EQADC_CFCR_AMODE0_MASK (15U << 0)
|
||||
#define EQADC_CFCR_AMODE0(n) ((n) << 0)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name EQADC FISR registers definitions
|
||||
* @{
|
||||
*/
|
||||
#define EQADC_FISR_POPNXTPTR_MASK (15U << 0)
|
||||
#define EQADC_FISR_RFCTR_MASK (15U << 4)
|
||||
#define EQADC_FISR_TNXTPTR_MASK (15U << 8)
|
||||
#define EQADC_FISR_CFCTR_MASK (15U << 12)
|
||||
#define EQADC_FISR_RFDF (1U << 17)
|
||||
#define EQADC_FISR_RFOF (1U << 19)
|
||||
#define EQADC_FISR_CFFF (1U << 25)
|
||||
#define EQADC_FISR_SSS (1U << 26)
|
||||
#define EQADC_FISR_CFUF (1U << 27)
|
||||
#define EQADC_FISR_EOQF (1U << 28)
|
||||
#define EQADC_FISR_PF (1U << 29)
|
||||
#define EQADC_FISR_TORF (1U << 30)
|
||||
#define EQADC_FISR_NCF (1U << 31)
|
||||
#define EQADC_FISR_CLEAR_MASK (EQADC_FISR_NCF | EQADC_FISR_TORF | \
|
||||
EQADC_FISR_PF | EQADC_FISR_EOQF | \
|
||||
EQADC_FISR_CFUF | EQADC_FISR_RFOF | \
|
||||
EQADC_FISR_RFDF)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name EQADC conversion/configuration commands
|
||||
* @{
|
||||
*/
|
||||
#define EQADC_CONV_CONFIG_STD (0U << 0) /**< @brief Alt.config.1. */
|
||||
#define EQADC_CONV_CONFIG_SEL1 (8U << 0) /**< @brief Alt.config.1. */
|
||||
#define EQADC_CONV_CONFIG_SEL2 (9U << 0) /**< @brief Alt.config.2. */
|
||||
#define EQADC_CONV_CONFIG_SEL3 (10U << 0) /**< @brief Alt.config.3. */
|
||||
#define EQADC_CONV_CONFIG_SEL4 (11U << 0) /**< @brief Alt.config.4. */
|
||||
#define EQADC_CONV_CONFIG_SEL5 (12U << 0) /**< @brief Alt.config.5. */
|
||||
#define EQADC_CONV_CONFIG_SEL6 (13U << 0) /**< @brief Alt.config.6. */
|
||||
#define EQADC_CONV_CONFIG_SEL7 (14U << 0) /**< @brief Alt.config.7. */
|
||||
#define EQADC_CONV_CONFIG_SEL8 (15U << 0) /**< @brief Alt.config.8. */
|
||||
#define EQADC_CONV_CHANNEL_MASK (255U << 8) /**< @brief Channel number mask.*/
|
||||
#define EQADC_CONV_CHANNEL(n) ((n) << 8) /**< @brief Channel number. */
|
||||
#define EQADC_CONV_FMT_RJU (0U << 16) /**< @brief Unsigned samples. */
|
||||
#define EQADC_CONV_FMT_RJS (1U << 16) /**< @brief Signed samples. */
|
||||
#define EQADC_CONV_TSR (1U << 17) /**< @brief Time stamp request. */
|
||||
#define EQADC_CONV_LST_MASK (3U << 18) /**< @brief Sample time. */
|
||||
#define EQADC_CONV_LST_2 (0U << 18) /**< @brief 2 clock cycles. */
|
||||
#define EQADC_CONV_LST_8 (1U << 18) /**< @brief 8 clock cycles. */
|
||||
#define EQADC_CONV_LST_64 (2U << 18) /**< @brief 64 clock cycles. */
|
||||
#define EQADC_CONV_LST_128 (3U << 18) /**< @brief 128 clock cycles. */
|
||||
#define EQADC_CONV_MSG_MASK (15U << 20) /**< @brief Message mask. */
|
||||
#define EQADC_CONV_MSG_RFIFO(n) ((n) << 20) /**< @brief Result in RFIFO0..5.*/
|
||||
#define EQADC_CONV_MSG_NULL (6U << 20) /**< @brief Null message. */
|
||||
#define EQADC_CONV_CAL (1U << 24) /**< @brief Calibrated result. */
|
||||
#define EQADC_CONV_BN_MASK (1U << 25) /**< @brief Buffer number mask. */
|
||||
#define EQADC_CONV_BN_ADC0 (0U << 25) /**< @brief ADC0 selection. */
|
||||
#define EQADC_CONV_BN_ADC1 (1U << 25) /**< @brief ADC1 selection. */
|
||||
#define EQADC_CONV_REP (1U << 29) /**< @brief Repeat loop flag. */
|
||||
#define EQADC_CONV_PAUSE (1U << 30) /**< @brief Pause flag. */
|
||||
#define EQADC_CONV_EOQ (1U << 31) /**< @brief End of queue flag. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name EQADC read/write commands
|
||||
* @{
|
||||
*/
|
||||
#define EQADC_RW_REG_ADDR_MASK (255U << 0)
|
||||
#define EQADC_RW_REG_ADDR(n) ((n) << 0)
|
||||
#define EQADC_RW_VALUE_MASK (0xFFFF << 8)
|
||||
#define EQADC_RW_VALUE(n) ((n) << 8)
|
||||
#define EQADC_RW_WRITE (0U << 24)
|
||||
#define EQADC_RW_READ (1U << 24)
|
||||
#define EQADC_RW_BN_ADC0 (0U << 25)
|
||||
#define EQADC_RW_BN_ADC1 (1U << 25)
|
||||
#define EQADC_RW_REP (1U << 29)
|
||||
#define EQADC_RW_PAUSE (1U << 30)
|
||||
#define EQADC_RW_EOQ (1U << 31)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name ADC CR register definitions
|
||||
* @{
|
||||
*/
|
||||
#define ADC_CR_CLK_PS_MASK (31U << 0)
|
||||
#define ADC_CR_CLK_PS(n) ((((n) >> 1) - 1) | ((n) & 1 ? ADC_CR_ODD_PS\
|
||||
: 0))
|
||||
#define ADC_CR_CLK_SEL (1U << 5)
|
||||
#define ADC_CR_CLK_DTY (1U << 6)
|
||||
#define ADC_CR_ODD_PS (1U << 7)
|
||||
#define ADC_CR_TBSEL_MASK (3U << 8)
|
||||
#define ADC_CR_TBSEL(n) ((n) << 8)
|
||||
#define ADC_CR_EMUX (1U << 11)
|
||||
#define ADC_CR_EN (1U << 15)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name ADC AxCR registers definitions
|
||||
* @{
|
||||
*/
|
||||
#define ADC_ACR_PRE_GAIN_MASK (3U << 0)
|
||||
#define ADC_ACR_PRE_GAIN_X1 (0U << 0)
|
||||
#define ADC_ACR_PRE_GAIN_X2 (1U << 0)
|
||||
#define ADC_ACR_PRE_GAIN_X4 (2U << 0)
|
||||
#define ADC_ACR_RESSEL_MASK (3U << 6)
|
||||
#define ADC_ACR_RESSEL_12BITS (0U << 6)
|
||||
#define ADC_ACR_RESSEL_10BITS (1U << 6)
|
||||
#define ADC_ACR_RESSEL_8BITS (2U << 6)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name ADC PUDCRx registers definitions
|
||||
* @{
|
||||
*/
|
||||
#define ADC_PUDCR_NONE 0x0000
|
||||
#define ADC_PUDCR_UP_200K 0x1100
|
||||
#define ADC_PUDCR_UP_100K 0x1200
|
||||
#define ADC_PUDCR_UP_5K 0x1300
|
||||
#define ADC_PUDCR_DOWN_200K 0x2100
|
||||
#define ADC_PUDCR_DOWN_100K 0x2200
|
||||
#define ADC_PUDCR_DOWN_5K 0x2300
|
||||
#define ADC_PUDCR_UP_DOWN_200K 0x3100
|
||||
#define ADC_PUDCR_UP_DOWN_100K 0x3200
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief ADCD1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ADC0 queue 0 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ADC_USE_ADC0_Q0) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_USE_ADC0_Q0 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADCD2 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ADC0 queue 1 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ADC_USE_ADC0_Q1) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_USE_ADC0_Q1 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADCD3 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ADC0 queue 2 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ADC_USE_ADC0_Q2) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_USE_ADC0_Q2 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADCD4 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ADC1 queue 3 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ADC_USE_ADC1_Q3) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_USE_ADC1_Q3 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADCD5 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ADC1 queue 4 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ADC_USE_ADC1_Q4) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_USE_ADC1_Q4 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADCD6 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ADC1 queue 5 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ADC_USE_ADC1_Q5) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_USE_ADC1_Q5 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EQADC CFIFO0 and RFIFO0 DMA priority.
|
||||
*/
|
||||
#if !defined(SPC5_ADC_FIFO0_DMA_PRIO) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_FIFO0_DMA_PRIO 12
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EQADC CFIFO1 and RFIFO1 DMA priority.
|
||||
*/
|
||||
#if !defined(SPC5_ADC_FIFO1_DMA_PRIO) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_FIFO1_DMA_PRIO 12
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EQADC CFIFO2 and RFIFO2 DMA priority.
|
||||
*/
|
||||
#if !defined(SPC5_ADC_FIFO2_DMA_PRIO) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_FIFO2_DMA_PRIO 12
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EQADC CFIFO3 and RFIFO3 DMA priority.
|
||||
*/
|
||||
#if !defined(SPC5_ADC_FIFO3_DMA_PRIO) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_FIFO3_DMA_PRIO 12
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EQADC CFIFO4 and RFIFO4 DMA priority.
|
||||
*/
|
||||
#if !defined(SPC5_ADC_FIFO4_DMA_PRIO) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_FIFO4_DMA_PRIO 12
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EQADC CFIFO5 and RFIFO5 DMA priority.
|
||||
*/
|
||||
#if !defined(SPC5_ADC_FIFO5_DMA_PRIO) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_FIFO5_DMA_PRIO 12
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EQADC CFIFO0 and RFIFO0 DMA IRQ priority.
|
||||
*/
|
||||
#if !defined(SPC5_ADC0_FIFO0_DMA_IRQ_PRIO) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_FIFO0_DMA_IRQ_PRIO 12
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EQADC CFIFO1 and RFIFO1 DMA IRQ priority.
|
||||
*/
|
||||
#if !defined(SPC5_ADC0_FIFO1_DMA_IRQ_PRIO) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_FIFO1_DMA_IRQ_PRIO 12
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EQADC CFIFO2 and RFIFO2 DMA IRQ priority.
|
||||
*/
|
||||
#if !defined(SPC5_ADC0_FIFO2_DMA_IRQ_PRIO) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_FIFO2_DMA_IRQ_PRIO 12
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EQADC CFIFO3 and RFIFO3 DMA IRQ priority.
|
||||
*/
|
||||
#if !defined(SPC5_ADC0_FIFO3_DMA_IRQ_PRIO) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_FIFO3_DMA_IRQ_PRIO 12
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EQADC CFIFO4 and RFIFO4 DMA IRQ priority.
|
||||
*/
|
||||
#if !defined(SPC5_ADC0_FIFO4_DMA_IRQ_PRIO) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_FIFO4_DMA_IRQ_PRIO 12
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EQADC CFIFO5 and RFIFO5 DMA IRQ priority.
|
||||
*/
|
||||
#if !defined(SPC5_ADC0_FIFO5_DMA_IRQ_PRIO) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_FIFO5_DMA_IRQ_PRIO 12
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EQADC clock prescaler value.
|
||||
*/
|
||||
#if !defined(SPC5_ADC_CR_CLK_PS) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_CR_CLK_PS ADC_CR_CLK_PS(5)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialization value for PUDCRx registers.
|
||||
*/
|
||||
#if !defined(SPC5_ADC_PUDCR) || defined(__DOXYGEN__)
|
||||
#define SPC5_ADC_PUDCR {ADC_PUDCR_NONE, \
|
||||
ADC_PUDCR_NONE, \
|
||||
ADC_PUDCR_NONE, \
|
||||
ADC_PUDCR_NONE, \
|
||||
ADC_PUDCR_NONE, \
|
||||
ADC_PUDCR_NONE, \
|
||||
ADC_PUDCR_NONE, \
|
||||
ADC_PUDCR_NONE}
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !SPC5_HAS_EQADC
|
||||
#error "EQADC not present in the selected device"
|
||||
#endif
|
||||
|
||||
#define SPC5_ADC_USE_ADC0 (SPC5_ADC_USE_ADC0_Q0 || \
|
||||
SPC5_ADC_USE_ADC0_Q1 || \
|
||||
SPC5_ADC_USE_ADC0_Q2)
|
||||
#define SPC5_ADC_USE_ADC1 (SPC5_ADC_USE_ADC1_Q3 || \
|
||||
SPC5_ADC_USE_ADC1_Q4 || \
|
||||
SPC5_ADC_USE_ADC1_Q5)
|
||||
|
||||
#if !SPC5_ADC_USE_ADC0 && !SPC5_ADC_USE_ADC1
|
||||
#error "ADC driver activated but no ADC peripheral assigned"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*!
|
||||
* @brief FIFO unit numeric IDs.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_FIFO_0 = 0,
|
||||
ADC_FIFO_1 = 1,
|
||||
ADC_FIFO_2 = 2,
|
||||
ADC_FIFO_3 = 3,
|
||||
ADC_FIFO_4 = 4,
|
||||
ADC_FIFO_5 = 5
|
||||
} adcfifo_t;
|
||||
|
||||
/**
|
||||
* @brief ADC command data type.
|
||||
*/
|
||||
typedef uint32_t adccommand_t;
|
||||
|
||||
/**
|
||||
* @brief ADC sample data type.
|
||||
*/
|
||||
typedef uint16_t adcsample_t;
|
||||
|
||||
/**
|
||||
* @brief Channels number in a conversion group.
|
||||
*/
|
||||
typedef uint16_t adc_channels_num_t;
|
||||
|
||||
/**
|
||||
* @brief Possible ADC failure causes.
|
||||
* @note Error codes are architecture dependent and should not relied
|
||||
* upon.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_ERR_DMAFAILURE = 0 /**< DMA operations failure. */
|
||||
} adcerror_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a structure representing an ADC driver.
|
||||
*/
|
||||
typedef struct ADCDriver ADCDriver;
|
||||
|
||||
/**
|
||||
* @brief ADC notification callback type.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object triggering the
|
||||
* callback
|
||||
* @param[in] buffer pointer to the most recent samples data
|
||||
* @param[in] n number of buffer rows available starting from @p buffer
|
||||
*/
|
||||
typedef void (*adccallback_t)(ADCDriver *adcp, adcsample_t *buffer, size_t n);
|
||||
|
||||
/**
|
||||
* @brief ADC error callback type.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object triggering the
|
||||
* callback
|
||||
* @param[in] err ADC error code
|
||||
*/
|
||||
typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err);
|
||||
|
||||
/**
|
||||
* @brief Conversion group configuration structure.
|
||||
* @details This implementation-dependent structure describes a conversion
|
||||
* operation.
|
||||
* @note Implementations may extend this structure to contain more,
|
||||
* architecture dependent, fields.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Enables the circular buffer mode for the group.
|
||||
*/
|
||||
bool_t circular;
|
||||
/**
|
||||
* @brief Number of the analog channels belonging to the conversion group.
|
||||
*/
|
||||
adc_channels_num_t num_channels;
|
||||
/**
|
||||
* @brief Callback function associated to the group or @p NULL.
|
||||
*/
|
||||
adccallback_t end_cb;
|
||||
/**
|
||||
* @brief Error callback or @p NULL.
|
||||
*/
|
||||
adcerrorcallback_t error_cb;
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Initialization value for CFCR register.
|
||||
*/
|
||||
uint16_t cfcr;
|
||||
/**
|
||||
* @brief SIU ETISR.TSEL value for this queue;
|
||||
*/
|
||||
uint8_t tsel;
|
||||
/**
|
||||
* @brief SIU ISEL3.ETSEL value for this queue;
|
||||
*/
|
||||
uint8_t etsel;
|
||||
/**
|
||||
* @brief Number of command iterations stored in @p commands.
|
||||
* @note The total number of array elements must be @p num_channels *
|
||||
* @p num_iterations.
|
||||
* @note This fields is the upper limit of the parameter @p n that can
|
||||
* be passed to the functions @p adcConvert() and
|
||||
* @p adcStartConversion().
|
||||
*/
|
||||
uint32_t num_iterations;
|
||||
/**
|
||||
* @brief Pointer to an array of low level EQADC commands to be pushed
|
||||
* into the CFIFO during a conversion.
|
||||
*/
|
||||
const adccommand_t *commands;
|
||||
} ADCConversionGroup;
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note Empty in this implementation can be ignored.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t dummy;
|
||||
} ADCConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing an ADC driver.
|
||||
*/
|
||||
struct ADCDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
adcstate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const ADCConfig *config;
|
||||
/**
|
||||
* @brief Current samples buffer pointer or @p NULL.
|
||||
*/
|
||||
adcsample_t *samples;
|
||||
/**
|
||||
* @brief Current samples buffer depth or @p 0.
|
||||
*/
|
||||
size_t depth;
|
||||
/**
|
||||
* @brief Current conversion group pointer or @p NULL.
|
||||
*/
|
||||
const ADCConversionGroup *grpp;
|
||||
#if ADC_USE_WAIT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Waiting thread.
|
||||
*/
|
||||
Thread *thread;
|
||||
#endif
|
||||
#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
|
||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Mutex protecting the peripheral.
|
||||
*/
|
||||
Mutex mutex;
|
||||
#elif CH_USE_SEMAPHORES
|
||||
Semaphore semaphore;
|
||||
#endif
|
||||
#endif /* ADC_USE_MUTUAL_EXCLUSION */
|
||||
#if defined(ADC_DRIVER_EXT_FIELDS)
|
||||
ADC_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief CFIFO/RFIFO used by this instance.
|
||||
*/
|
||||
adcfifo_t fifo;
|
||||
/**
|
||||
* @brief EDMA channel used for the CFIFO.
|
||||
*/
|
||||
edma_channel_t cfifo_channel;
|
||||
/**
|
||||
* @brief EDMA channel used for the RFIFO.
|
||||
*/
|
||||
edma_channel_t rfifo_channel;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if SPC5_ADC_USE_ADC0_Q0 && !defined(__DOXYGEN__)
|
||||
extern ADCDriver ADCD1;
|
||||
#endif
|
||||
|
||||
#if SPC5_ADC_USE_ADC0_Q1 && !defined(__DOXYGEN__)
|
||||
extern ADCDriver ADCD2;
|
||||
#endif
|
||||
|
||||
#if SPC5_ADC_USE_ADC0_Q2 && !defined(__DOXYGEN__)
|
||||
extern ADCDriver ADCD3;
|
||||
#endif
|
||||
|
||||
#if SPC5_ADC_USE_ADC1_Q3 && !defined(__DOXYGEN__)
|
||||
extern ADCDriver ADCD4;
|
||||
#endif
|
||||
|
||||
#if SPC5_ADC_USE_ADC1_Q4 && !defined(__DOXYGEN__)
|
||||
extern ADCDriver ADCD5;
|
||||
#endif
|
||||
|
||||
#if SPC5_ADC_USE_ADC1_Q5 && !defined(__DOXYGEN__)
|
||||
extern ADCDriver ADCD6;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void adc_lld_init(void);
|
||||
void adc_lld_start(ADCDriver *adcp);
|
||||
void adc_lld_stop(ADCDriver *adcp);
|
||||
void adc_lld_start_conversion(ADCDriver *adcp);
|
||||
void adc_lld_stop_conversion(ADCDriver *adcp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_ADC */
|
||||
|
||||
#endif /* _ADC_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 SPC5xx/ESCI_v1/serial_lld.c
|
||||
* @brief SPC5xx low level serial driver code.
|
||||
*
|
||||
* @addtogroup SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief eSCI-A serial driver identifier.
|
||||
*/
|
||||
#if SPC5_USE_ESCIA || defined(__DOXYGEN__)
|
||||
SerialDriver SD1;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief eSCI-B serial driver identifier.
|
||||
*/
|
||||
#if SPC5_USE_ESCIB || defined(__DOXYGEN__)
|
||||
SerialDriver SD2;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Driver default configuration.
|
||||
*/
|
||||
static const SerialConfig default_config = {
|
||||
SERIAL_DEFAULT_BITRATE,
|
||||
SD_MODE_NORMAL | SD_MODE_PARITY_NONE
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief eSCI initialization.
|
||||
* @details This function must be invoked with interrupts disabled.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
* @param[in] config the architecture-dependent serial driver configuration
|
||||
*/
|
||||
static void esci_init(SerialDriver *sdp, const SerialConfig *config) {
|
||||
volatile struct ESCI_tag *escip = sdp->escip;
|
||||
uint8_t mode = config->sc_mode;
|
||||
|
||||
escip->CR2.R = 0; /* MDIS off. */
|
||||
escip->CR1.R = 0;
|
||||
escip->LCR.R = 0;
|
||||
escip->CR1.B.SBR = SPC5_SYSCLK / (16 * config->sc_speed);
|
||||
if (mode & SD_MODE_LOOPBACK)
|
||||
escip->CR1.B.LOOPS = 1;
|
||||
switch (mode & SD_MODE_PARITY_MASK) {
|
||||
case SD_MODE_PARITY_ODD:
|
||||
escip->CR1.B.PT = 1;
|
||||
case SD_MODE_PARITY_EVEN:
|
||||
escip->CR1.B.PE = 1;
|
||||
escip->CR1.B.M = 1; /* Makes it 8 bits data + 1 bit parity. */
|
||||
default:
|
||||
;
|
||||
}
|
||||
escip->LPR.R = 0;
|
||||
escip->CR1.R |= 0x0000002C; /* RIE, TE, RE to 1. */
|
||||
escip->CR2.R = 0x000F; /* ORIE, NFIE, FEIE, PFIE to 1. */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief eSCI de-initialization.
|
||||
* @details This function must be invoked with interrupts disabled.
|
||||
*
|
||||
* @param[in] escip pointer to an eSCI I/O block
|
||||
*/
|
||||
static void esci_deinit(volatile struct ESCI_tag *escip) {
|
||||
|
||||
escip->LPR.R = 0;
|
||||
escip->SR.R = 0xFFFFFFFF;
|
||||
escip->CR1.R = 0;
|
||||
escip->CR2.R = 0x8000; /* MDIS on. */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Error handling routine.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
* @param[in] sr eSCI SR register value
|
||||
*/
|
||||
static void set_error(SerialDriver *sdp, uint32_t sr) {
|
||||
flagsmask_t sts = 0;
|
||||
|
||||
if (sr & 0x08000000)
|
||||
sts |= SD_OVERRUN_ERROR;
|
||||
if (sr & 0x04000000)
|
||||
sts |= SD_NOISE_ERROR;
|
||||
if (sr & 0x02000000)
|
||||
sts |= SD_FRAMING_ERROR;
|
||||
if (sr & 0x01000000)
|
||||
sts |= SD_PARITY_ERROR;
|
||||
/* if (sr & 0x00000000)
|
||||
sts |= SD_BREAK_DETECTED;*/
|
||||
chSysLockFromIsr();
|
||||
chnAddFlagsI(sdp, sts);
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common IRQ handler.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
*/
|
||||
static void serve_interrupt(SerialDriver *sdp) {
|
||||
volatile struct ESCI_tag *escip = sdp->escip;
|
||||
|
||||
uint32_t sr = escip->SR.R;
|
||||
escip->SR.R = 0x3FFFFFFF; /* Does not clear TDRE | TC.*/
|
||||
if (sr & 0x0F000000) /* OR | NF | FE | PF. */
|
||||
set_error(sdp, sr);
|
||||
if (sr & 0x20000000) { /* RDRF. */
|
||||
chSysLockFromIsr();
|
||||
sdIncomingDataI(sdp, escip->DR.B.D);
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
if (escip->CR1.B.TIE && (sr & 0x80000000)) { /* TDRE. */
|
||||
msg_t b;
|
||||
chSysLockFromIsr();
|
||||
b = chOQGetI(&sdp->oqueue);
|
||||
if (b < Q_OK) {
|
||||
chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
|
||||
escip->CR1.B.TIE = 0;
|
||||
}
|
||||
else {
|
||||
ESCI_A.SR.B.TDRE = 1;
|
||||
escip->DR.R = (uint16_t)b;
|
||||
}
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
}
|
||||
|
||||
#if SPC5_USE_ESCIA || defined(__DOXYGEN__)
|
||||
static void notify1(GenericQueue *qp) {
|
||||
|
||||
(void)qp;
|
||||
if (ESCI_A.SR.B.TDRE) {
|
||||
msg_t b = sdRequestDataI(&SD1);
|
||||
if (b != Q_EMPTY) {
|
||||
ESCI_A.SR.B.TDRE = 1;
|
||||
ESCI_A.CR1.B.TIE = 1;
|
||||
ESCI_A.DR.R = (uint16_t)b;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SPC5_USE_ESCIB || defined(__DOXYGEN__)
|
||||
static void notify2(GenericQueue *qp) {
|
||||
|
||||
(void)qp;
|
||||
if (ESCI_B.SR.B.TDRE) {
|
||||
msg_t b = sdRequestDataI(&SD2);
|
||||
if (b != Q_EMPTY) {
|
||||
ESCI_B.SR.B.TDRE = 1;
|
||||
ESCI_B.CR1.B.TIE = 1;
|
||||
ESCI_B.DR.R = (uint16_t)b;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if SPC5_USE_ESCIA || defined(__DOXYGEN__)
|
||||
#if !defined(SPC5_ESCIA_HANDLER)
|
||||
#error "SPC5_ESCIA_HANDLER not defined"
|
||||
#endif
|
||||
/**
|
||||
* @brief eSCI-A interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(SPC5_ESCIA_HANDLER) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
serve_interrupt(&SD1);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SPC5_USE_ESCIB || defined(__DOXYGEN__)
|
||||
#if !defined(SPC5_ESCIB_HANDLER)
|
||||
#error "SPC5_ESCIB_HANDLER not defined"
|
||||
#endif
|
||||
/**
|
||||
* @brief eSCI-B interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(SPC5_ESCIB_HANDLER) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
serve_interrupt(&SD2);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_init(void) {
|
||||
|
||||
#if SPC5_USE_ESCIA
|
||||
sdObjectInit(&SD1, NULL, notify1);
|
||||
SD1.escip = &ESCI_A;
|
||||
ESCI_A.CR2.R = 0x8000; /* MDIS ON. */
|
||||
INTC.PSR[SPC5_ESCIA_NUMBER].R = SPC5_ESCIA_PRIORITY;
|
||||
#endif
|
||||
|
||||
#if SPC5_USE_ESCIB
|
||||
sdObjectInit(&SD2, NULL, notify2);
|
||||
SD2.escip = &ESCI_B;
|
||||
ESCI_B.CR2.R = 0x8000; /* MDIS ON. */
|
||||
INTC.PSR[SPC5_ESCIB_NUMBER].R = SPC5_ESCIB_PRIORITY;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver configuration and (re)start.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
* @param[in] config the architecture-dependent serial driver configuration.
|
||||
* If this parameter is set to @p NULL then a default
|
||||
* configuration is used.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
|
||||
|
||||
if (config == NULL)
|
||||
config = &default_config;
|
||||
esci_init(sdp, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver stop.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_stop(SerialDriver *sdp) {
|
||||
|
||||
if (sdp->state == SD_READY)
|
||||
esci_deinit(sdp->escip);
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_SERIAL */
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 SPC5xx/ESCI_v1/serial_lld.c
|
||||
* @brief SPC5xx low level serial driver header.
|
||||
*
|
||||
* @addtogroup SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _SERIAL_LLD_H_
|
||||
#define _SERIAL_LLD_H_
|
||||
|
||||
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Serial port modes
|
||||
* @{
|
||||
*/
|
||||
#define SD_MODE_PARITY_MASK 0x03 /**< @brief Parity field mask. */
|
||||
#define SD_MODE_PARITY_NONE 0x00 /**< @brief No parity. */
|
||||
#define SD_MODE_PARITY_EVEN 0x01 /**< @brief Even parity. */
|
||||
#define SD_MODE_PARITY_ODD 0x02 /**< @brief Odd parity. */
|
||||
|
||||
#define SD_MODE_NORMAL 0x00 /**< @brief Normal operations. */
|
||||
#define SD_MODE_LOOPBACK 0x80 /**< @brief Internal loopback. */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief eSCI-A driver enable switch.
|
||||
* @details If set to @p TRUE the support for eSCI-A is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(SPC5_USE_ESCIA) || defined(__DOXYGEN__)
|
||||
#define SPC5_USE_ESCIA TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief eSCI-B driver enable switch.
|
||||
* @details If set to @p TRUE the support for eSCI-B is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(SPC5_USE_ESCIB) || defined(__DOXYGEN__)
|
||||
#define SPC5_USE_ESCIB TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief eSCI-A interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC_ESCIA_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_ESCIA_PRIORITY 8
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief eSCI-B interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC_ESCIB_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_ESCIB_PRIORITY 8
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if SPC5_USE_ESCIA && !SPC5_HAS_ESCIA
|
||||
#error "eSCI-A not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if SPC5_USE_ESCIB && !SPC5_HAS_ESCIB
|
||||
#error "eSCI-B not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if !SPC5_USE_ESCIA && !SPC5_USE_ESCIB
|
||||
#error "SERIAL driver activated but no eSCI peripheral assigned"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Generic Serial Driver configuration structure.
|
||||
* @details An instance of this structure must be passed to @p sdStart()
|
||||
* in order to configure and start a serial driver operations.
|
||||
* @note This structure content is architecture dependent, each driver
|
||||
* implementation defines its own version and the custom static
|
||||
* initializers.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Bit rate.
|
||||
*/
|
||||
uint32_t sc_speed;
|
||||
/**
|
||||
* @brief Mode flags.
|
||||
*/
|
||||
uint8_t sc_mode;
|
||||
} SerialConfig;
|
||||
|
||||
/**
|
||||
* @brief @p SerialDriver specific data.
|
||||
*/
|
||||
#define _serial_driver_data \
|
||||
_base_asynchronous_channel_data \
|
||||
/* Driver state.*/ \
|
||||
sdstate_t state; \
|
||||
/* Input queue.*/ \
|
||||
InputQueue iqueue; \
|
||||
/* Output queue.*/ \
|
||||
OutputQueue oqueue; \
|
||||
/* Input circular buffer.*/ \
|
||||
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
|
||||
/* Output circular buffer.*/ \
|
||||
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
|
||||
/* End of the mandatory fields.*/ \
|
||||
/* Pointer to the volatile eSCI registers block.*/ \
|
||||
volatile struct ESCI_tag *escip;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if SPC5_USE_ESCIA && !defined(__DOXYGEN__)
|
||||
extern SerialDriver SD1;
|
||||
#endif
|
||||
#if SPC5_USE_ESCIB && !defined(__DOXYGEN__)
|
||||
extern SerialDriver SD2;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void sd_lld_init(void);
|
||||
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
|
||||
void sd_lld_stop(SerialDriver *sdp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_SERIAL */
|
||||
|
||||
#endif /* _SERIAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
+1776
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,475 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 FlexPWM_v1/pwm_lld.h
|
||||
* @brief SPC5xx low level PWM driver header.
|
||||
*
|
||||
* @addtogroup PWM
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _PWM_LLD_H_
|
||||
#define _PWM_LLD_H_
|
||||
|
||||
#if HAL_USE_PWM || defined(__DOXYGEN__)
|
||||
|
||||
#include "spc5_flexpwm.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name STS register bits definitions
|
||||
* @{
|
||||
*/
|
||||
#define SPC5_FLEXPWM_STS_CMPF0 (1U << 0)
|
||||
#define SPC5_FLEXPWM_STS_CMPF1 (1U << 1)
|
||||
#define SPC5_FLEXPWM_STS_CMPF2 (1U << 2)
|
||||
#define SPC5_FLEXPWM_STS_CMPF3 (1U << 3)
|
||||
#define SPC5_FLEXPWM_STS_CMPF4 (1U << 4)
|
||||
#define SPC5_FLEXPWM_STS_CMPF5 (1U << 5)
|
||||
#define SPC5_FLEXPWM_STS_CFX0 (1U << 6)
|
||||
#define SPC5_FLEXPWM_STS_CFX1 (1U << 7)
|
||||
#define SPC5_FLEXPWM_STS_RF (1U << 12)
|
||||
#define SPC5_FLEXPWM_STS_REF (1U << 13)
|
||||
#define SPC5_FLEXPWM_STS_RUF (1U << 14)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name PSC values definition
|
||||
* @{
|
||||
*/
|
||||
#define SPC5_FLEXPWM_PSC_1 0U
|
||||
#define SPC5_FLEXPWM_PSC_2 1U
|
||||
#define SPC5_FLEXPWM_PSC_4 2U
|
||||
#define SPC5_FLEXPWM_PSC_8 3U
|
||||
#define SPC5_FLEXPWM_PSC_16 4U
|
||||
#define SPC5_FLEXPWM_PSC_32 5U
|
||||
#define SPC5_FLEXPWM_PSC_64 6U
|
||||
#define SPC5_FLEXPWM_PSC_128 7U
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Number of PWM channels per PWM driver.
|
||||
*/
|
||||
#define PWM_CHANNELS 2
|
||||
|
||||
/**
|
||||
* @brief Complementary output modes mask.
|
||||
* @note This is an SPC5-specific setting.
|
||||
*/
|
||||
#define PWM_COMPLEMENTARY_OUTPUT_MASK 0xF0
|
||||
|
||||
/**
|
||||
* @brief Complementary output not driven.
|
||||
* @note This is an SPC5-specific setting.
|
||||
*/
|
||||
#define PWM_COMPLEMENTARY_OUTPUT_DISABLED 0x00
|
||||
|
||||
/**
|
||||
* @brief Complementary output, active is logic level one.
|
||||
* @note This is an SPC5-specific setting.
|
||||
*/
|
||||
#define PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH 0x10
|
||||
|
||||
/**
|
||||
* @brief Complementary output, active is logic level zero.
|
||||
* @note This is an SPC5-specific setting.
|
||||
*/
|
||||
#define PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW 0x20
|
||||
|
||||
/**
|
||||
* @brief Alignment mode mask.
|
||||
* @note This is an SPC5-specific setting.
|
||||
*/
|
||||
#define PWM_ALIGN_MASK 0x01
|
||||
|
||||
/**
|
||||
* @brief Edge-Aligned PWM functional mode.
|
||||
* @note This is an SPC5-specific setting.
|
||||
*/
|
||||
#define PWM_ALIGN_EDGE 0x00
|
||||
|
||||
/**
|
||||
* @brief Center-Aligned PWM functional mode.
|
||||
* @note This is an SPC5-specific setting.
|
||||
*/
|
||||
#define PWM_ALIGN_CENTER 0x01
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief PWMD1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for PWMD1 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_USE_SMOD0) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_USE_SMOD0 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD2 driver enable switch.
|
||||
* @details If set to @p TRUE the support for PWMD2 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_USE_SMOD1) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_USE_SMOD1 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD3 driver enable switch.
|
||||
* @details If set to @p TRUE the support for PWMD3 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_USE_SMOD2) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_USE_SMOD2 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD4 driver enable switch.
|
||||
* @details If set to @p TRUE the support for PWMD4 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_USE_SMOD3) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_USE_SMOD3 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD1 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_SMOD0_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_SMOD0_PRIORITY 7
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD2 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_SMOD1_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_SMOD1_PRIORITY 7
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD3 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_SMOD2_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_SMOD2_PRIORITY 7
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD4 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_SMOD3_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_SMOD3_PRIORITY 7
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief FlexPWM-0 peripheral configuration when started.
|
||||
* @note The default configuration is 1 (always run) in run mode and
|
||||
* 2 (only halt) in low power mode. The defaults of the run modes
|
||||
* are defined in @p hal_lld.h.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_FLEXPWM0_START_PCTL) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_FLEXPWM0_START_PCTL (SPC5_ME_PCTL_RUN(1) | \
|
||||
SPC5_ME_PCTL_LP(2))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief FlexPWM-0 peripheral configuration when stopped.
|
||||
* @note The default configuration is 0 (never run) in run mode and
|
||||
* 0 (never run) in low power mode. The defaults of the run modes
|
||||
* are defined in @p hal_lld.h.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_FLEXPWM0_STOP_PCTL) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_FLEXPWM0_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \
|
||||
SPC5_ME_PCTL_LP(0))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD5 driver enable switch.
|
||||
* @details If set to @p TRUE the support for PWMD5 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_USE_SMOD4) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_USE_SMOD4 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD6 driver enable switch.
|
||||
* @details If set to @p TRUE the support for PWMD6 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_USE_SMOD5) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_USE_SMOD5 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD7 driver enable switch.
|
||||
* @details If set to @p TRUE the support for PWMD7 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_USE_SMOD6) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_USE_SMOD6 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD8 driver enable switch.
|
||||
* @details If set to @p TRUE the support for PWMD8 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_USE_SMOD7) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_USE_SMOD7 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD5 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_SMOD4_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_SMOD4_PRIORITY 7
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD6 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_SMOD5_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_SMOD5_PRIORITY 7
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD7 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_SMOD6_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_SMOD6_PRIORITY 7
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD8 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_SMOD7_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_SMOD7_PRIORITY 7
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief FlexPWM-1 peripheral configuration when started.
|
||||
* @note The default configuration is 1 (always run) in run mode and
|
||||
* 2 (only halt) in low power mode. The defaults of the run modes
|
||||
* are defined in @p hal_lld.h.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_FLEXPWM1_START_PCTL) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_FLEXPWM1_START_PCTL (SPC5_ME_PCTL_RUN(1) | \
|
||||
SPC5_ME_PCTL_LP(2))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief FlexPWM-1 peripheral configuration when stopped.
|
||||
* @note The default configuration is 0 (never run) in run mode and
|
||||
* 0 (never run) in low power mode. The defaults of the run modes
|
||||
* are defined in @p hal_lld.h.
|
||||
*/
|
||||
#if !defined(SPC5_PWM_FLEXPWM1_STOP_PCTL) || defined(__DOXYGEN__)
|
||||
#define SPC5_PWM_FLEXPWM1_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \
|
||||
SPC5_ME_PCTL_LP(0))
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Configuration checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define SPC5_PWM_USE_FLEXPWM0 (SPC5_PWM_USE_SMOD0 || \
|
||||
SPC5_PWM_USE_SMOD1 || \
|
||||
SPC5_PWM_USE_SMOD2 || \
|
||||
SPC5_PWM_USE_SMOD3)
|
||||
|
||||
#define SPC5_PWM_USE_FLEXPWM1 (SPC5_PWM_USE_SMOD4 || \
|
||||
SPC5_PWM_USE_SMOD5 || \
|
||||
SPC5_PWM_USE_SMOD6 || \
|
||||
SPC5_PWM_USE_SMOD7)
|
||||
|
||||
#if !SPC5_HAS_FLEXPWM0 && SPC5_PWM_USE_FLEXPWM0
|
||||
#error "FlexPWM0 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if !SPC5_HAS_FLEXPWM1 && SPC5_PWM_USE_FLEXPWM1
|
||||
#error "FlexPWM1 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if !SPC5_PWM_USE_FLEXPWM0 && !SPC5_PWM_USE_FLEXPWM1
|
||||
#error "PWM driver activated but no PWM peripheral assigned"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief PWM mode type.
|
||||
*/
|
||||
typedef uint32_t pwmmode_t;
|
||||
|
||||
/**
|
||||
* @brief PWM channel type.
|
||||
*/
|
||||
typedef uint8_t pwmchannel_t;
|
||||
|
||||
/**
|
||||
* @brief PWM counter type.
|
||||
*/
|
||||
typedef uint16_t pwmcnt_t;
|
||||
|
||||
/**
|
||||
* @brief PWM driver channel configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Channel active logic level.
|
||||
*/
|
||||
pwmmode_t mode;
|
||||
/**
|
||||
* @brief Channel callback pointer.
|
||||
* @note This callback is invoked on the channel compare event. If set to
|
||||
* @p NULL then the callback is disabled.
|
||||
*/
|
||||
pwmcallback_t callback;
|
||||
/* End of the mandatory fields.*/
|
||||
} PWMChannelConfig;
|
||||
|
||||
/**
|
||||
* @brief PWM driver configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Timer clock in Hz.
|
||||
* @note The low level can use assertions in order to catch invalid
|
||||
* frequency specifications.
|
||||
*/
|
||||
uint32_t frequency;
|
||||
/**
|
||||
* @brief PWM period in ticks.
|
||||
* @note The low level can use assertions in order to catch invalid
|
||||
* period specifications.
|
||||
*/
|
||||
pwmcnt_t period;
|
||||
/**
|
||||
* @brief Periodic callback pointer.
|
||||
* @note This callback is invoked on PWM counter reset. If set to
|
||||
* @p NULL then the callback is disabled.
|
||||
*/
|
||||
pwmcallback_t callback;
|
||||
/**
|
||||
* @brief Channels configurations.
|
||||
*/
|
||||
PWMChannelConfig channels[PWM_CHANNELS];
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief PWM functional mode.
|
||||
*/
|
||||
pwmmode_t mode;
|
||||
} PWMConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing a PWM driver.
|
||||
*/
|
||||
struct PWMDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
pwmstate_t state;
|
||||
/**
|
||||
* @brief Current driver configuration data.
|
||||
*/
|
||||
const PWMConfig *config;
|
||||
/**
|
||||
* @brief Current PWM period in ticks.
|
||||
*/
|
||||
pwmcnt_t period;
|
||||
#if defined(PWM_DRIVER_EXT_FIELDS)
|
||||
PWM_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @Pointer to the volatile FlexPWM registers block.
|
||||
*/
|
||||
volatile struct spc5_flexpwm *flexpwmp;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if SPC5_PWM_USE_SMOD0 && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD1;
|
||||
#endif
|
||||
|
||||
#if SPC5_PWM_USE_SMOD1 && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD2;
|
||||
#endif
|
||||
|
||||
#if SPC5_PWM_USE_SMOD2 && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD3;
|
||||
#endif
|
||||
|
||||
#if SPC5_PWM_USE_SMOD3 && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD4;
|
||||
#endif
|
||||
|
||||
#if SPC5_PWM_USE_SMOD4 && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD5;
|
||||
#endif
|
||||
|
||||
#if SPC5_PWM_USE_SMOD5 && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD6;
|
||||
#endif
|
||||
|
||||
#if SPC5_PWM_USE_SMOD6 && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD7;
|
||||
#endif
|
||||
|
||||
#if SPC5_PWM_USE_SMOD7 && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD8;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void pwm_lld_init(void);
|
||||
void pwm_lld_start(PWMDriver *pwmp);
|
||||
void pwm_lld_stop(PWMDriver *pwmp);
|
||||
void pwm_lld_enable_channel(PWMDriver *pwmp,
|
||||
pwmchannel_t channel,
|
||||
pwmcnt_t width);
|
||||
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
|
||||
void pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_PWM */
|
||||
|
||||
#endif /* _PWM_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 FlexPWM_v1/spc5_flexpwm.h
|
||||
* @brief SPC5xx FlexPWM header file.
|
||||
*
|
||||
* @addtogroup PWM
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _SPC5_FLEXPWM_H_
|
||||
#define _SPC5_FLEXPWM_H_
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief SPC5 FlexPWM registers block.
|
||||
* @note Redefined from the SPC5 headers because the non uniform
|
||||
* declaration of the SubModules registers among the various
|
||||
* sub-families.
|
||||
*/
|
||||
struct spc5_flexpwm_submodule {
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
} CNT; /* Counter Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
} INIT; /* Initial Count Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t DBGEN :1;
|
||||
vuint16_t WAITEN :1;
|
||||
vuint16_t INDEP :1;
|
||||
vuint16_t PWMA_INIT :1;
|
||||
vuint16_t PWMB_INIT :1;
|
||||
vuint16_t PWMX_INIT :1;
|
||||
vuint16_t INIT_SEL :2;
|
||||
vuint16_t FRCEN :1;
|
||||
vuint16_t FORCE :1;
|
||||
vuint16_t FORCE_SEL :3;
|
||||
vuint16_t RELOAD_SEL :1;
|
||||
vuint16_t CLK_SEL :2;
|
||||
} B;
|
||||
} CTRL2; /* Control 2 Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t LDFQ :4;
|
||||
vuint16_t HALF :1;
|
||||
vuint16_t FULL :1;
|
||||
vuint16_t DT :2;
|
||||
vuint16_t :1;
|
||||
vuint16_t PRSC :3;
|
||||
vuint16_t :3;
|
||||
vuint16_t DBLEN :1;
|
||||
} B;
|
||||
} CTRL; /* Control Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
} VAL[6]; /* Value Register 0->5 */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t FRACAEN :1;
|
||||
vuint16_t :10;
|
||||
vuint16_t FRACADLY :5;
|
||||
} B;
|
||||
} FRACA; /* Fractional Delay Register A */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t FRACBEN :1;
|
||||
vuint16_t :10;
|
||||
vuint16_t FRACBDLY :5;
|
||||
} B;
|
||||
} FRACB; /* Fractional Delay Register B */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t PWMA_IN :1;
|
||||
vuint16_t PWMB_IN :1;
|
||||
vuint16_t PWMX_IN :1;
|
||||
vuint16_t :2;
|
||||
vuint16_t POLA :1;
|
||||
vuint16_t POLB :1;
|
||||
vuint16_t POLX :1;
|
||||
vuint16_t :2;
|
||||
vuint16_t PWMAFS :2;
|
||||
vuint16_t PWMBFS :2;
|
||||
vuint16_t PWMXFS :2;
|
||||
} B;
|
||||
} OCTRL; /* Output Control Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :1;
|
||||
vuint16_t RUF :1;
|
||||
vuint16_t REF :1;
|
||||
vuint16_t RF :1;
|
||||
vuint16_t CFA1 :1;
|
||||
vuint16_t CFA0 :1;
|
||||
vuint16_t CFB1 :1;
|
||||
vuint16_t CFB0 :1;
|
||||
vuint16_t CFX1 :1;
|
||||
vuint16_t CFX0 :1;
|
||||
vuint16_t CMPF :6;
|
||||
} B;
|
||||
} STS; /* Status Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :2;
|
||||
vuint16_t REIE :1;
|
||||
vuint16_t RIE :1;
|
||||
vuint16_t :4;
|
||||
vuint16_t CX1IE :1;
|
||||
vuint16_t CX0IE :1;
|
||||
vuint16_t CMPIE :6;
|
||||
} B;
|
||||
} INTEN; /* Interrupt Enable Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :6;
|
||||
vuint16_t VALDE :1;
|
||||
vuint16_t FAND :1;
|
||||
vuint16_t CAPTDE :2;
|
||||
vuint16_t CA1DE :1;
|
||||
vuint16_t CA0DE :1;
|
||||
vuint16_t CB1DE :1;
|
||||
vuint16_t CB0DE :1;
|
||||
vuint16_t CX1DE :1;
|
||||
vuint16_t CX0DE :1;
|
||||
} B;
|
||||
} DMAEN; /* DMA Enable Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :10;
|
||||
vuint16_t OUT_TRIG_EN :6;
|
||||
} B;
|
||||
} TCTRL; /* Output Trigger Control Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :4;
|
||||
vuint16_t DISX :4;
|
||||
vuint16_t DISB :4;
|
||||
vuint16_t DISA :4;
|
||||
} B;
|
||||
} DISMAP; /* Fault Disable Mapping Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :5;
|
||||
vuint16_t DTCNT0 :11;
|
||||
} B;
|
||||
} DTCNT0; /* Deadtime Count Register 0 */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :5;
|
||||
vuint16_t DTCNT1 :11;
|
||||
} B;
|
||||
} DTCNT1; /* Deadtime Count Register 1 */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CA1CNT :3;
|
||||
vuint16_t CA0CNT :3;
|
||||
vuint16_t CFAWM :2;
|
||||
vuint16_t EDGCNTAEN :1;
|
||||
vuint16_t INPSELA :1;
|
||||
vuint16_t EDGA1 :2;
|
||||
vuint16_t EDGA0 :2;
|
||||
vuint16_t ONESHOTA :1;
|
||||
vuint16_t ARMA :1;
|
||||
} B;
|
||||
} CAPTCTRLA; /* Capture Control Register A */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t EDGCNTA :8;
|
||||
vuint16_t EDGCMPA :8;
|
||||
} B;
|
||||
} CAPTCOMPA; /* Capture Compare Register A */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CB1CNT :3;
|
||||
vuint16_t CB0CNT :3;
|
||||
vuint16_t CFBWM :2;
|
||||
vuint16_t EDGCNTBEN :1;
|
||||
vuint16_t INPSELB :1;
|
||||
vuint16_t EDGB1 :2;
|
||||
vuint16_t EDGB0 :2;
|
||||
vuint16_t ONESHOTB :1;
|
||||
vuint16_t ARMB :1;
|
||||
} B;
|
||||
} CAPTCTRLB; /* Capture Control Register B */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t EDGCNTB :8;
|
||||
vuint16_t EDGCMPB :8;
|
||||
} B;
|
||||
} CAPTCOMPB; /* Capture Compare Register B */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CX1CNT :3;
|
||||
vuint16_t CX0CNT :3;
|
||||
vuint16_t CFXWM :2;
|
||||
vuint16_t EDGCNTX_EN :1;
|
||||
vuint16_t INP_SELX :1;
|
||||
vuint16_t EDGX1 :2;
|
||||
vuint16_t EDGX0 :2;
|
||||
vuint16_t ONESHOTX :1;
|
||||
vuint16_t ARMX :1;
|
||||
} B;
|
||||
} CAPTCTRLX; /* Capture Control Register B */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t EDGCNTX :8;
|
||||
vuint16_t EDGCMPX :8;
|
||||
} B;
|
||||
} CAPTCOMPX; /* Capture Compare Register X */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CAPTVAL0 :16;
|
||||
} B;
|
||||
} CVAL0; /* Capture Value 0 Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :12;
|
||||
vuint16_t CVAL0CYC :4;
|
||||
} B;
|
||||
} CVAL0C; /* Capture Value 0 Cycle Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CAPTVAL1 :16;
|
||||
} B;
|
||||
} CVAL1; /* Capture Value 1 Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :12;
|
||||
vuint16_t CVAL1CYC :4;
|
||||
} B;
|
||||
} CVAL1C; /* Capture Value 1 Cycle Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CAPTVAL2 :16;
|
||||
} B;
|
||||
} CVAL2; /* Capture Value 2 Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :12;
|
||||
vuint16_t CVAL2CYC :4;
|
||||
} B;
|
||||
} CVAL2C; /* Capture Value 2 Cycle Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CAPTVAL3 :16;
|
||||
} B;
|
||||
} CVAL3; /* Capture Value 3 Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :12;
|
||||
vuint16_t CVAL3CYC :4;
|
||||
} B;
|
||||
} CVAL3C; /* Capture Value 3 Cycle Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CAPTVAL4 :16;
|
||||
} B;
|
||||
} CVAL4; /* Capture Value 4 Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :12;
|
||||
vuint16_t CVAL4CYC :4;
|
||||
} B;
|
||||
} CVAL4C; /* Capture Value 4 Cycle Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CAPTVAL5 :16;
|
||||
} B;
|
||||
} CVAL5; /* Capture Value 5 Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :12;
|
||||
vuint16_t CVAL5CYC :4;
|
||||
} B;
|
||||
} CVAL5C; /* Capture Value 5 Cycle Register */
|
||||
|
||||
uint32_t FLEXPWM_SUB_reserved0; /* (0x04A - 0x050)/4 = 0x01 */
|
||||
|
||||
};
|
||||
/* end of FLEXPWM_SUB_tag */
|
||||
|
||||
struct spc5_flexpwm {
|
||||
|
||||
struct spc5_flexpwm_submodule SUB[4];
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :4;
|
||||
vuint16_t PWMA_EN :4;
|
||||
vuint16_t PWMB_EN :4;
|
||||
vuint16_t PWMX_EN :4;
|
||||
} B;
|
||||
} OUTEN; /* Output Enable Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :4;
|
||||
vuint16_t MASKA :4;
|
||||
vuint16_t MASKB :4;
|
||||
vuint16_t MASKX :4;
|
||||
} B;
|
||||
} MASK; /* Output Mask Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :8;
|
||||
vuint16_t OUTA_3 :1;
|
||||
vuint16_t OUTB_3 :1;
|
||||
vuint16_t OUTA_2 :1;
|
||||
vuint16_t OUTB_2 :1;
|
||||
vuint16_t OUTA_1 :1;
|
||||
vuint16_t OUTB_1 :1;
|
||||
vuint16_t OUTA_0 :1;
|
||||
vuint16_t OUTB_0 :1;
|
||||
} B;
|
||||
} SWCOUT; /* Software Controlled Output Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t SELA_3 :2;
|
||||
vuint16_t SELB_3 :2;
|
||||
vuint16_t SELA_2 :2;
|
||||
vuint16_t SELB_2 :2;
|
||||
vuint16_t SELA_1 :2;
|
||||
vuint16_t SELB_1 :2;
|
||||
vuint16_t SELA_0 :2;
|
||||
vuint16_t SELB_0 :2;
|
||||
} B;
|
||||
} DTSRCSEL; /* Deadtime Source Select Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t IPOL :4;
|
||||
vuint16_t RUN :4;
|
||||
vuint16_t CLDOK :4;
|
||||
vuint16_t LDOK :4;
|
||||
} B;
|
||||
} MCTRL; /* Master Control Register */
|
||||
|
||||
int16_t FLEXPWM_reserved1;
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t FLVL :4;
|
||||
vuint16_t FAUTO :4;
|
||||
vuint16_t FSAFE :4;
|
||||
vuint16_t FIE :4;
|
||||
} B;
|
||||
} FCTRL; /* Fault Control Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :3;
|
||||
vuint16_t FTEST :1;
|
||||
vuint16_t FFPIN :4;
|
||||
vuint16_t :4;
|
||||
vuint16_t FFLAG :4;
|
||||
} B;
|
||||
} FSTS; /* Fault Status Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :5;
|
||||
vuint16_t FILT_CNT :3;
|
||||
vuint16_t FILT_PER :8;
|
||||
} B;
|
||||
} FFILT; /* Fault FilterRegister */
|
||||
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name FlexPWM units references
|
||||
* @{
|
||||
*/
|
||||
#if SPC5_HAS_FLEXPWM0 || defined(__DOXYGEN__)
|
||||
#define SPC5_FLEXPWM_0 (*(volatile struct spc5_flexpwm *)0xFFE24000UL)
|
||||
#endif
|
||||
|
||||
#if SPC5_HAS_FLEXPWM1 || defined(__DOXYGEN__)
|
||||
#define SPC5_FLEXPWM_1 (*(volatile struct spc5_flexpwm *)0xFFE28000UL)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#endif /* _SPC5_FLEXPWM_H_ */
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,426 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 SPC5xx/LINFlex_v1/serial_lld.c
|
||||
* @brief SPC5xx low level serial driver code.
|
||||
*
|
||||
* @addtogroup SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief LIINFlex-0 serial driver identifier.
|
||||
*/
|
||||
#if SPC5_SERIAL_USE_LINFLEX0 || defined(__DOXYGEN__)
|
||||
SerialDriver SD1;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LIINFlex-1 serial driver identifier.
|
||||
*/
|
||||
#if SPC5_SERIAL_USE_LINFLEX1 || defined(__DOXYGEN__)
|
||||
SerialDriver SD2;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LIINFlex-2 serial driver identifier.
|
||||
*/
|
||||
#if SPC5_SERIAL_USE_LINFLEX2 || defined(__DOXYGEN__)
|
||||
SerialDriver SD3;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LIINFlex-3 serial driver identifier.
|
||||
*/
|
||||
#if SPC5_SERIAL_USE_LINFLEX3 || defined(__DOXYGEN__)
|
||||
SerialDriver SD4;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Driver default configuration.
|
||||
*/
|
||||
static const SerialConfig default_config = {
|
||||
SERIAL_DEFAULT_BITRATE,
|
||||
SD_MODE_8BITS_PARITY_NONE
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief LINFlex initialization.
|
||||
* @details This function must be invoked with interrupts disabled.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
* @param[in] config the architecture-dependent serial driver configuration
|
||||
*/
|
||||
static void spc5_linflex_init(SerialDriver *sdp, const SerialConfig *config) {
|
||||
uint32_t div;
|
||||
volatile struct LINFLEX_tag *linflexp = sdp->linflexp;
|
||||
|
||||
/* Enters the configuration mode.*/
|
||||
linflexp->LINCR1.R = 1; /* INIT bit. */
|
||||
|
||||
/* Configures the LINFlex in UART mode with all the required
|
||||
parameters.*/
|
||||
linflexp->UARTCR.R = SPC5_UARTCR_UART; /* UART mode FIRST. */
|
||||
linflexp->UARTCR.R = SPC5_UARTCR_UART | SPC5_UARTCR_RXEN | config->mode;
|
||||
div = SPC5_LINFLEX0_CLK / config->speed;
|
||||
linflexp->LINFBRR.R = (uint16_t)(div & 15); /* Fractional divider. */
|
||||
linflexp->LINIBRR.R = (uint16_t)(div >> 4); /* Integer divider. */
|
||||
linflexp->UARTSR.R = 0xFFFF; /* Clearing UARTSR register.*/
|
||||
linflexp->LINIER.R = SPC5_LINIER_DTIE | SPC5_LINIER_DRIE |
|
||||
SPC5_LINIER_BOIE | SPC5_LINIER_FEIE |
|
||||
SPC5_LINIER_SZIE; /* Interrupts enabled. */
|
||||
|
||||
/* Leaves the configuration mode.*/
|
||||
linflexp->LINCR1.R = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LINFlex de-initialization.
|
||||
* @details This function must be invoked with interrupts disabled.
|
||||
*
|
||||
* @param[in] linflexp pointer to a LINFlex I/O block
|
||||
*/
|
||||
static void spc5_linflex_deinit(volatile struct LINFLEX_tag *linflexp) {
|
||||
|
||||
/* Enters the configuration mode.*/
|
||||
linflexp->LINCR1.R = 1; /* INIT bit. */
|
||||
|
||||
/* Resets the LINFlex registers.*/
|
||||
linflexp->LINFBRR.R = 0; /* Fractional divider. */
|
||||
linflexp->LINIBRR.R = 0; /* Integer divider. */
|
||||
linflexp->UARTSR.R = 0xFFFF; /* Clearing UARTSR register.*/
|
||||
linflexp->UARTCR.R = SPC5_UARTCR_UART;
|
||||
linflexp->LINIER.R = 0; /* Interrupts disabled. */
|
||||
|
||||
/* Leaves the configuration mode.*/
|
||||
linflexp->LINCR1.R = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common RXI IRQ handler.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
*/
|
||||
static void spc5xx_serve_rxi_interrupt(SerialDriver *sdp) {
|
||||
flagsmask_t sts = 0;
|
||||
uint16_t sr = sdp->linflexp->UARTSR.R;
|
||||
|
||||
sdp->linflexp->UARTSR.R = SPC5_UARTSR_NF | SPC5_UARTSR_DRF |
|
||||
SPC5_UARTSR_PE0;
|
||||
if (sr & SPC5_UARTSR_NF)
|
||||
sts |= SD_NOISE_ERROR;
|
||||
if (sr & SPC5_UARTSR_PE0)
|
||||
sts |= SD_PARITY_ERROR;
|
||||
chSysLockFromIsr();
|
||||
if (sts)
|
||||
chnAddFlagsI(sdp, sts);
|
||||
if (sr & SPC5_UARTSR_DRF) {
|
||||
sdIncomingDataI(sdp, sdp->linflexp->BDRM.B.DATA4);
|
||||
sdp->linflexp->UARTSR.R = SPC5_UARTSR_RMB;
|
||||
}
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common TXI IRQ handler.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
*/
|
||||
static void spc5xx_serve_txi_interrupt(SerialDriver *sdp) {
|
||||
msg_t b;
|
||||
|
||||
sdp->linflexp->UARTSR.R = SPC5_UARTSR_DTF;
|
||||
chSysLockFromIsr();
|
||||
b = chOQGetI(&sdp->oqueue);
|
||||
if (b < Q_OK) {
|
||||
chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
|
||||
sdp->linflexp->UARTCR.B.TXEN = 0;
|
||||
}
|
||||
else
|
||||
sdp->linflexp->BDRL.B.DATA0 = b;
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common ERR IRQ handler.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
*/
|
||||
static void spc5xx_serve_err_interrupt(SerialDriver *sdp) {
|
||||
flagsmask_t sts = 0;
|
||||
uint16_t sr = sdp->linflexp->UARTSR.R;
|
||||
|
||||
sdp->linflexp->UARTSR.R = SPC5_UARTSR_BOF | SPC5_UARTSR_FEF |
|
||||
SPC5_UARTSR_SZF;
|
||||
if (sr & SPC5_UARTSR_BOF)
|
||||
sts |= SD_OVERRUN_ERROR;
|
||||
if (sr & SPC5_UARTSR_FEF)
|
||||
sts |= SD_FRAMING_ERROR;
|
||||
if (sr & SPC5_UARTSR_SZF)
|
||||
sts |= SD_BREAK_DETECTED;
|
||||
chSysLockFromIsr();
|
||||
chnAddFlagsI(sdp, sts);
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
|
||||
#if SPC5_SERIAL_USE_LINFLEX0 || defined(__DOXYGEN__)
|
||||
static void notify1(GenericQueue *qp) {
|
||||
|
||||
(void)qp;
|
||||
if (!SD1.linflexp->UARTCR.B.TXEN) {
|
||||
msg_t b = sdRequestDataI(&SD1);
|
||||
if (b != Q_EMPTY) {
|
||||
SD1.linflexp->UARTCR.B.TXEN = 1;
|
||||
SD1.linflexp->BDRL.B.DATA0 = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SPC5_SERIAL_USE_LINFLEX1 || defined(__DOXYGEN__)
|
||||
static void notify2(GenericQueue *qp) {
|
||||
|
||||
(void)qp;
|
||||
if (!SD2.linflexp->UARTCR.B.TXEN) {
|
||||
msg_t b = sdRequestDataI(&SD2);
|
||||
if (b != Q_EMPTY) {
|
||||
SD2.linflexp->UARTCR.B.TXEN = 1;
|
||||
SD2.linflexp->BDRL.B.DATA0 = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if SPC5_SERIAL_USE_LINFLEX0 || defined(__DOXYGEN__)
|
||||
#if !defined(SPC5_LINFLEX0_RXI_HANDLER)
|
||||
#error "SPC5_LINFLEX0_RXI_HANDLER not defined"
|
||||
#endif
|
||||
/**
|
||||
* @brief LINFlex-0 RXI interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(SPC5_LINFLEX0_RXI_HANDLER) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
spc5xx_serve_rxi_interrupt(&SD1);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
#if !defined(SPC5_LINFLEX0_TXI_HANDLER)
|
||||
#error "SPC5_LINFLEX0_TXI_HANDLER not defined"
|
||||
#endif
|
||||
/**
|
||||
* @brief LINFlex-0 TXI interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(SPC5_LINFLEX0_TXI_HANDLER) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
spc5xx_serve_txi_interrupt(&SD1);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
#if !defined(SPC5_LINFLEX0_ERR_HANDLER)
|
||||
#error "SPC5_LINFLEX0_ERR_HANDLER not defined"
|
||||
#endif
|
||||
/**
|
||||
* @brief LINFlex-0 ERR interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(SPC5_LINFLEX0_ERR_HANDLER) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
spc5xx_serve_err_interrupt(&SD1);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SPC5_SERIAL_USE_LINFLEX1 || defined(__DOXYGEN__)
|
||||
#if !defined(SPC5_LINFLEX1_RXI_HANDLER)
|
||||
#error "SPC5_LINFLEX1_RXI_HANDLER not defined"
|
||||
#endif
|
||||
/**
|
||||
* @brief LINFlex-1 RXI interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(SPC5_LINFLEX1_RXI_HANDLER) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
spc5xx_serve_rxi_interrupt(&SD2);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
#if !defined(SPC5_LINFLEX1_TXI_HANDLER)
|
||||
#error "SPC5_LINFLEX1_TXI_HANDLER not defined"
|
||||
#endif
|
||||
/**
|
||||
* @brief LINFlex-1 TXI interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(SPC5_LINFLEX1_TXI_HANDLER) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
spc5xx_serve_txi_interrupt(&SD2);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
#if !defined(SPC5_LINFLEX1_ERR_HANDLER)
|
||||
#error "SPC5_LINFLEX1_ERR_HANDLER not defined"
|
||||
#endif
|
||||
/**
|
||||
* @brief LINFlex-1 ERR interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(SPC5_LINFLEX1_ERR_HANDLER) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
spc5xx_serve_err_interrupt(&SD2);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_init(void) {
|
||||
|
||||
#if SPC5_SERIAL_USE_LINFLEX0
|
||||
sdObjectInit(&SD1, NULL, notify1);
|
||||
SD1.linflexp = &LINFLEX_0;
|
||||
INTC.PSR[SPC5_LINFLEX0_RXI_NUMBER].R = SPC5_SERIAL_LINFLEX0_PRIORITY;
|
||||
INTC.PSR[SPC5_LINFLEX0_TXI_NUMBER].R = SPC5_SERIAL_LINFLEX0_PRIORITY;
|
||||
INTC.PSR[SPC5_LINFLEX0_ERR_NUMBER].R = SPC5_SERIAL_LINFLEX0_PRIORITY;
|
||||
#endif
|
||||
|
||||
#if SPC5_SERIAL_USE_LINFLEX1
|
||||
sdObjectInit(&SD2, NULL, notify2);
|
||||
SD2.linflexp = &LINFLEX_1;
|
||||
INTC.PSR[SPC5_LINFLEX1_RXI_NUMBER].R = SPC5_SERIAL_LINFLEX1_PRIORITY;
|
||||
INTC.PSR[SPC5_LINFLEX1_TXI_NUMBER].R = SPC5_SERIAL_LINFLEX1_PRIORITY;
|
||||
INTC.PSR[SPC5_LINFLEX1_ERR_NUMBER].R = SPC5_SERIAL_LINFLEX1_PRIORITY;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver configuration and (re)start.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
* @param[in] config the architecture-dependent serial driver configuration.
|
||||
* If this parameter is set to @p NULL then a default
|
||||
* configuration is used.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
|
||||
|
||||
if (config == NULL)
|
||||
config = &default_config;
|
||||
|
||||
if (sdp->state == SD_STOP) {
|
||||
#if SPC5_SERIAL_USE_LINFLEX0
|
||||
if (&SD1 == sdp) {
|
||||
halSPCSetPeripheralClockMode(SPC5_LINFLEX0_PCTL,
|
||||
SPC5_SERIAL_LINFLEX0_START_PCTL);
|
||||
}
|
||||
#endif
|
||||
#if SPC5_SERIAL_USE_LINFLEX1
|
||||
if (&SD2 == sdp) {
|
||||
halSPCSetPeripheralClockMode(SPC5_LINFLEX1_PCTL,
|
||||
SPC5_SERIAL_LINFLEX1_START_PCTL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
spc5_linflex_init(sdp, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver stop.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_stop(SerialDriver *sdp) {
|
||||
|
||||
if (sdp->state == SD_READY) {
|
||||
spc5_linflex_deinit(sdp->linflexp);
|
||||
|
||||
#if SPC5_SERIAL_USE_LINFLEX0
|
||||
if (&SD1 == sdp) {
|
||||
halSPCSetPeripheralClockMode(SPC5_LINFLEX0_PCTL,
|
||||
SPC5_SERIAL_LINFLEX0_STOP_PCTL);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if SPC5_SERIAL_USE_LINFLEX1
|
||||
if (&SD2 == sdp) {
|
||||
halSPCSetPeripheralClockMode(SPC5_LINFLEX1_PCTL,
|
||||
SPC5_SERIAL_LINFLEX1_STOP_PCTL);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_SERIAL */
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 SPC5xx/LINFlex_v1/serial_lld.h
|
||||
* @brief SPC5xx low level serial driver header.
|
||||
*
|
||||
* @addtogroup SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _SERIAL_LLD_H_
|
||||
#define _SERIAL_LLD_H_
|
||||
|
||||
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name LINIER register bits definitions
|
||||
* @{
|
||||
*/
|
||||
#define SPC5_LINIER_HRIE (1U << 0)
|
||||
#define SPC5_LINIER_DTIE (1U << 1)
|
||||
#define SPC5_LINIER_DRIE (1U << 2)
|
||||
#define SPC5_LINIER_DBEIE (1U << 3)
|
||||
#define SPC5_LINIER_DBFIE (1U << 4)
|
||||
#define SPC5_LINIER_WUIE (1U << 5)
|
||||
#define SPC5_LINIER_LSIE (1U << 6)
|
||||
#define SPC5_LINIER_BOIE (1U << 7)
|
||||
#define SPC5_LINIER_FEIE (1U << 8)
|
||||
#define SPC5_LINIER_HEIE (1U << 11)
|
||||
#define SPC5_LINIER_CEIE (1U << 12)
|
||||
#define SPC5_LINIER_BEIE (1U << 13)
|
||||
#define SPC5_LINIER_OCIE (1U << 14)
|
||||
#define SPC5_LINIER_SZIE (1U << 15)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name UARTSR register bits definitions
|
||||
* @{
|
||||
*/
|
||||
#define SPC5_UARTSR_NF (1U << 0)
|
||||
#define SPC5_UARTSR_DTF (1U << 1)
|
||||
#define SPC5_UARTSR_DRF (1U << 2)
|
||||
#define SPC5_UARTSR_WUF (1U << 5)
|
||||
#define SPC5_UARTSR_RPS (1U << 6)
|
||||
#define SPC5_UARTSR_BOF (1U << 7)
|
||||
#define SPC5_UARTSR_FEF (1U << 8)
|
||||
#define SPC5_UARTSR_RMB (1U << 9)
|
||||
#define SPC5_UARTSR_PE0 (1U << 10)
|
||||
#define SPC5_UARTSR_PE1 (1U << 11)
|
||||
#define SPC5_UARTSR_PE2 (1U << 12)
|
||||
#define SPC5_UARTSR_PE3 (1U << 13)
|
||||
#define SPC5_UARTSR_OCF (1U << 14)
|
||||
#define SPC5_UARTSR_SZF (1U << 15)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name UARTCR register bits definitions
|
||||
* @{
|
||||
*/
|
||||
#define SPC5_UARTCR_UART (1U << 0)
|
||||
#define SPC5_UARTCR_WL (1U << 1)
|
||||
#define SPC5_UARTCR_PCE (1U << 2)
|
||||
#define SPC5_UARTCR_OP (1U << 3)
|
||||
#define SPC5_UARTCR_TXEN (1U << 4)
|
||||
#define SPC5_UARTCR_RXEN (1U << 5)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Serial driver allowable modes
|
||||
* @{
|
||||
*/
|
||||
#define SD_MODE_8BITS_PARITY_NONE (SPC5_UARTCR_WL)
|
||||
#define SD_MODE_8BITS_PARITY_EVEN (SPC5_UARTCR_WL | \
|
||||
SPC5_UARTCR_PCE)
|
||||
#define SD_MODE_8BITS_PARITY_ODD (SPC5_UARTCR_WL | \
|
||||
SPC5_UARTCR_PCE | \
|
||||
SPC5_UARTCR_OP)
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief LINFlex-0 driver enable switch.
|
||||
* @details If set to @p TRUE the support for LINFlex-0 is included.
|
||||
*/
|
||||
#if !defined(SPC5_SERIAL_USE_LINFLEX0) || defined(__DOXYGEN__)
|
||||
#define SPC5_SERIAL_USE_LINFLEX0 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LINFlex-1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for LINFlex-1 is included.
|
||||
*/
|
||||
#if !defined(SPC5_SERIAL_USE_LINFLEX1) || defined(__DOXYGEN__)
|
||||
#define SPC5_SERIAL_USE_LINFLEX1 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LINFlex-0 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC5_SERIAL_LINFLEX0_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_SERIAL_LINFLEX0_PRIORITY 8
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LINFlex-1 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC5_SERIAL_LINFLEX1_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_SERIAL_LINFLEX1_PRIORITY 8
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LINFlex-0 peripheral configuration when started.
|
||||
* @note The default configuration is 1 (always run) in run mode and
|
||||
* 2 (only halt) in low power mode. The defaults of the run modes
|
||||
* are defined in @p hal_lld.h.
|
||||
*/
|
||||
#if !defined(SPC5_SERIAL_LINFLEX0_START_PCTL) || defined(__DOXYGEN__)
|
||||
#define SPC5_SERIAL_LINFLEX0_START_PCTL (SPC5_ME_PCTL_RUN(1) | \
|
||||
SPC5_ME_PCTL_LP(2))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LINFlex-0 peripheral configuration when stopped.
|
||||
* @note The default configuration is 0 (never run) in run mode and
|
||||
* 0 (never run) in low power mode. The defaults of the run modes
|
||||
* are defined in @p hal_lld.h.
|
||||
*/
|
||||
#if !defined(SPC5_SERIAL_LINFLEX0_STOP_PCTL) || defined(__DOXYGEN__)
|
||||
#define SPC5_SERIAL_LINFLEX0_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \
|
||||
SPC5_ME_PCTL_LP(0))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LINFlex-1 peripheral configuration when started.
|
||||
* @note The default configuration is 1 (always run) in run mode and
|
||||
* 2 (only halt) in low power mode. The defaults of the run modes
|
||||
* are defined in @p hal_lld.h.
|
||||
*/
|
||||
#if !defined(SPC5_SERIAL_LINFLEX1_START_PCTL) || defined(__DOXYGEN__)
|
||||
#define SPC5_SERIAL_LINFLEX1_START_PCTL (SPC5_ME_PCTL_RUN(1) | \
|
||||
SPC5_ME_PCTL_LP(2))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LINFlex-1 peripheral configuration when stopped.
|
||||
* @note The default configuration is 0 (never run) in run mode and
|
||||
* 0 (never run) in low power mode. The defaults of the run modes
|
||||
* are defined in @p hal_lld.h.
|
||||
*/
|
||||
#if !defined(SPC5_SERIAL_LINFLEX1_STOP_PCTL) || defined(__DOXYGEN__)
|
||||
#define SPC5_SERIAL_LINFLEX1_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \
|
||||
SPC5_ME_PCTL_LP(0))
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if SPC5_SERIAL_USE_LINFLEX0 && !SPC5_HAS_LINFLEX0
|
||||
#error "LINFlex-0 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if SPC5_SERIAL_USE_LINFLEX1 && !SPC5_HAS_LINFLEX1
|
||||
#error "LINFlex-1 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if SPC5_SERIAL_USE_LINFLEX2 && !SPC5_HAS_LINFLEX2
|
||||
#error "LINFlex-2 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if SPC5_SERIAL_USE_LINFLEX3 && !SPC5_HAS_LINFLEX3
|
||||
#error "LINFlex-3 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if !SPC5_SERIAL_USE_LINFLEX0 && !SPC5_SERIAL_USE_LINFLEX1 && \
|
||||
!SPC5_SERIAL_USE_LINFLEX2 && !SPC5_SERIAL_USE_LINFLEX3
|
||||
#error "SERIAL driver activated but no LINFlex peripheral assigned"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Generic Serial Driver configuration structure.
|
||||
* @details An instance of this structure must be passed to @p sdStart()
|
||||
* in order to configure and start a serial driver operations.
|
||||
* @note This structure content is architecture dependent, each driver
|
||||
* implementation defines its own version and the custom static
|
||||
* initializers.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Bit rate.
|
||||
*/
|
||||
uint32_t speed;
|
||||
/**
|
||||
* @brief Mode flags.
|
||||
*/
|
||||
uint8_t mode;
|
||||
} SerialConfig;
|
||||
|
||||
/**
|
||||
* @brief @p SerialDriver specific data.
|
||||
*/
|
||||
#define _serial_driver_data \
|
||||
_base_asynchronous_channel_data \
|
||||
/* Driver state.*/ \
|
||||
sdstate_t state; \
|
||||
/* Input queue.*/ \
|
||||
InputQueue iqueue; \
|
||||
/* Output queue.*/ \
|
||||
OutputQueue oqueue; \
|
||||
/* Input circular buffer.*/ \
|
||||
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
|
||||
/* Output circular buffer.*/ \
|
||||
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
|
||||
/* End of the mandatory fields.*/ \
|
||||
/* Pointer to the volatile LINFlex registers block.*/ \
|
||||
volatile struct LINFLEX_tag *linflexp;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if SPC5_SERIAL_USE_LINFLEX0 && !defined(__DOXYGEN__)
|
||||
extern SerialDriver SD1;
|
||||
#endif
|
||||
#if SPC5_SERIAL_USE_LINFLEX1 && !defined(__DOXYGEN__)
|
||||
extern SerialDriver SD2;
|
||||
#endif
|
||||
#if SPC5_SERIAL_USE_LINFLEX2 && !defined(__DOXYGEN__)
|
||||
extern SerialDriver SD3;
|
||||
#endif
|
||||
#if SPC5_SERIAL_USE_LINFLEX3 && !defined(__DOXYGEN__)
|
||||
extern SerialDriver SD4;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void sd_lld_init(void);
|
||||
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
|
||||
void sd_lld_stop(SerialDriver *sdp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_SERIAL */
|
||||
|
||||
#endif /* _SERIAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 SPC5xx/SIUL_v1/pal_lld.c
|
||||
* @brief SPC5xx SIUL low level driver code.
|
||||
*
|
||||
* @addtogroup PAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if defined(SPC5_SIUL_SYSTEM_PINS)
|
||||
static const unsigned system_pins[] = {SPC5_SIUL_SYSTEM_PINS};
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief SPC5xx I/O ports configuration.
|
||||
*
|
||||
* @param[in] config the STM32 ports configuration
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _pal_lld_init(const PALConfig *config) {
|
||||
unsigned i;
|
||||
|
||||
#if defined(SPC5_SIUL_PCTL)
|
||||
/* SIUL clock gating if present.*/
|
||||
halSPCSetPeripheralClockMode(SPC5_SIUL_PCTL,
|
||||
SPC5_ME_PCTL_RUN(2) | SPC5_ME_PCTL_LP(2));
|
||||
#endif
|
||||
|
||||
/* Initialize PCR registers for undefined pads.*/
|
||||
for (i = 0; i < SPC5_SIUL_NUM_PCRS; i++) {
|
||||
#if defined(SPC5_SIUL_SYSTEM_PINS)
|
||||
/* Handling the case where some SIU pins are not meant to be reprogrammed,
|
||||
for example JTAG pins.*/
|
||||
unsigned j;
|
||||
for (j = 0; j < sizeof system_pins; j++) {
|
||||
if (i == system_pins[j])
|
||||
goto skip;
|
||||
}
|
||||
SIU.PCR[i].R = config->default_mode;
|
||||
skip:
|
||||
;
|
||||
#else
|
||||
SIU.PCR[i].R = config->default_mode;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize PADSEL registers.*/
|
||||
for (i = 0; i < SPC5_SIUL_NUM_PADSELS; i++)
|
||||
SIU.PSMI[i].R = config->padsels[i];
|
||||
|
||||
/* Initialize PCR registers for defined pads.*/
|
||||
i = 0;
|
||||
while (config->inits[i].pcr_value != 0) {
|
||||
SIU.GPDO[config->inits[i].pcr_index].R = config->inits[i].gpdo_value;
|
||||
SIU.PCR[config->inits[i].pcr_index].R = config->inits[i].pcr_value;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads a group of bits.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @return The group logical states.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
ioportmask_t _pal_lld_readgroup(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
uint_fast8_t offset) {
|
||||
|
||||
(void)port;
|
||||
(void)mask;
|
||||
(void)offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes a group of bits.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @param[in] bits bits to be written. Values exceeding the group width
|
||||
* are masked.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _pal_lld_writegroup(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
uint_fast8_t offset,
|
||||
ioportmask_t bits) {
|
||||
|
||||
(void)port;
|
||||
(void)mask;
|
||||
(void)offset;
|
||||
(void)bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pads mode setup.
|
||||
* @details This function programs a pads group belonging to the same port
|
||||
* with the specified mode.
|
||||
*
|
||||
* @param[in] port the port identifier
|
||||
* @param[in] mask the group mask
|
||||
* @param[in] mode the mode
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _pal_lld_setgroupmode(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
iomode_t mode) {
|
||||
unsigned pcr_index = (unsigned)(port * PAL_IOPORTS_WIDTH);
|
||||
ioportmask_t m1 = 0x8000;
|
||||
while (m1) {
|
||||
if (mask & m1)
|
||||
SIU.PCR[pcr_index].R = mode;
|
||||
m1 >>= 1;
|
||||
++pcr_index;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_PAL */
|
||||
|
||||
/** @} */
|
||||
+423
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 SPC5xx/SIUL_v1/pal_lld.h
|
||||
* @brief SPC5xx SIUL low level driver header.
|
||||
*
|
||||
* @addtogroup PAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _PAL_LLD_H_
|
||||
#define _PAL_LLD_H_
|
||||
|
||||
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Unsupported modes and specific modes */
|
||||
/*===========================================================================*/
|
||||
|
||||
#undef PAL_MODE_RESET
|
||||
#undef PAL_MODE_UNCONNECTED
|
||||
#undef PAL_MODE_INPUT
|
||||
#undef PAL_MODE_INPUT_PULLUP
|
||||
#undef PAL_MODE_INPUT_PULLDOWN
|
||||
#undef PAL_MODE_INPUT_ANALOG
|
||||
#undef PAL_MODE_OUTPUT_PUSHPULL
|
||||
#undef PAL_MODE_OUTPUT_OPENDRAIN
|
||||
|
||||
/**
|
||||
* @name SIUL-specific PAL modes
|
||||
* @{
|
||||
*/
|
||||
#define PAL_SPC5_SMC (1U << 14)
|
||||
#define PAL_SPC5_APC (1U << 13)
|
||||
#define PAL_SPC5_PA_MASK (3U << 10)
|
||||
#define PAL_SPC5_PA(n) ((n) << 10)
|
||||
#define PAL_SPC5_OBE (1U << 9)
|
||||
#define PAL_SPC5_IBE (1U << 8)
|
||||
#define PAL_SPC5_ODE (1U << 5)
|
||||
#define PAL_SPC5_SRC (1U << 2)
|
||||
#define PAL_SPC5_WPE (1U << 1)
|
||||
#define PAL_SPC5_WPS (1U << 0)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Pads mode constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief After reset state.
|
||||
*/
|
||||
#define PAL_MODE_RESET 0
|
||||
|
||||
/**
|
||||
* @brief Safe state for <b>unconnected</b> pads.
|
||||
*/
|
||||
#define PAL_MODE_UNCONNECTED (PAL_SPC5_WPE | PAL_SPC5_WPS)
|
||||
|
||||
/**
|
||||
* @brief Regular input high-Z pad.
|
||||
*/
|
||||
#define PAL_MODE_INPUT (PAL_SPC5_IBE)
|
||||
|
||||
/**
|
||||
* @brief Input pad with weak pull up resistor.
|
||||
*/
|
||||
#define PAL_MODE_INPUT_PULLUP (PAL_SPC5_IBE |PAL_SPC5_WPE | \
|
||||
PAL_SPC5_WPS)
|
||||
|
||||
/**
|
||||
* @brief Input pad with weak pull down resistor.
|
||||
*/
|
||||
#define PAL_MODE_INPUT_PULLDOWN (PAL_SPC5_IBE |PAL_SPC5_WPE)
|
||||
|
||||
/**
|
||||
* @brief Analog input mode.
|
||||
*/
|
||||
#define PAL_MODE_INPUT_ANALOG PAL_SPC5_APC
|
||||
|
||||
/**
|
||||
* @brief Push-pull output pad.
|
||||
*/
|
||||
#define PAL_MODE_OUTPUT_PUSHPULL (PAL_SPC5_IBE | PAL_SPC5_OBE)
|
||||
|
||||
/**
|
||||
* @brief Open-drain output pad.
|
||||
*/
|
||||
#define PAL_MODE_OUTPUT_OPENDRAIN (PAL_SPC5_IBE | PAL_SPC5_OBE | \
|
||||
PAL_SPC5_ODE)
|
||||
|
||||
/**
|
||||
* @brief Alternate "n" output pad.
|
||||
*/
|
||||
#define PAL_MODE_OUTPUT_ALTERNATE(n) (PAL_SPC5_IBE | PAL_SPC5_PA(n))
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I/O Ports Types and constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Width, in bits, of an I/O port.
|
||||
*/
|
||||
#define PAL_IOPORTS_WIDTH 16
|
||||
|
||||
/**
|
||||
* @brief Whole port mask.
|
||||
* @brief This macro specifies all the valid bits into a port.
|
||||
*/
|
||||
#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
|
||||
|
||||
/**
|
||||
* @brief Digital I/O port sized unsigned type.
|
||||
*/
|
||||
typedef uint16_t ioportmask_t;
|
||||
|
||||
/**
|
||||
* @brief Digital I/O modes.
|
||||
*/
|
||||
typedef uint16_t iomode_t;
|
||||
|
||||
/**
|
||||
* @brief Port Identifier.
|
||||
* @details This type can be a scalar or some kind of pointer, do not make
|
||||
* any assumption about it, use the provided macros when populating
|
||||
* variables of this type.
|
||||
*/
|
||||
typedef uint32_t ioportid_t;
|
||||
|
||||
/**
|
||||
* @brief SIUL register initializer type.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t pcr_index;
|
||||
uint8_t gpdo_value;
|
||||
iomode_t pcr_value;
|
||||
} spc_siu_init_t;
|
||||
|
||||
/**
|
||||
* @brief Generic I/O ports static initializer.
|
||||
* @details An instance of this structure must be passed to @p palInit() at
|
||||
* system startup time in order to initialized the digital I/O
|
||||
* subsystem. This represents only the initial setup, specific pads
|
||||
* or whole ports can be reprogrammed at later time.
|
||||
* @note Implementations may extend this structure to contain more,
|
||||
* architecture dependent, fields.
|
||||
*/
|
||||
typedef struct {
|
||||
iomode_t default_mode;
|
||||
const spc_siu_init_t *inits;
|
||||
const uint8_t *padsels;
|
||||
} PALConfig;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I/O Ports Identifiers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief I/O port A identifier.
|
||||
*/
|
||||
#define PORT_A 0
|
||||
|
||||
/**
|
||||
* @brief I/O port B identifier.
|
||||
*/
|
||||
#define PORT_B 1
|
||||
|
||||
/**
|
||||
* @brief I/O port C identifier.
|
||||
*/
|
||||
#define PORT_C 2
|
||||
|
||||
/**
|
||||
* @brief I/O port D identifier.
|
||||
*/
|
||||
#define PORT_D 3
|
||||
|
||||
/**
|
||||
* @brief I/O port E identifier.
|
||||
*/
|
||||
#define PORT_E 4
|
||||
|
||||
/**
|
||||
* @brief I/O port F identifier.
|
||||
*/
|
||||
#define PORT_F 5
|
||||
|
||||
/**
|
||||
* @brief I/O port G identifier.
|
||||
*/
|
||||
#define PORT_G 6
|
||||
|
||||
/**
|
||||
* @brief I/O port H identifier.
|
||||
*/
|
||||
#define PORT_H 7
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Implementation, some of the following macros could be implemented as */
|
||||
/* functions, if so please put them in pal_lld.c. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Port bit helper macro.
|
||||
* @note Overrides the one in @p pal.h.
|
||||
*
|
||||
* @param[in] n bit position within the port
|
||||
*
|
||||
* @return The bit mask.
|
||||
*/
|
||||
#define PAL_PORT_BIT(n) ((ioportmask_t)(0x8000U >> (n)))
|
||||
|
||||
/**
|
||||
* @brief Low level PAL subsystem initialization.
|
||||
*
|
||||
* @param[in] config architecture-dependent ports configuration
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_init(config) _pal_lld_init(config)
|
||||
|
||||
/**
|
||||
* @brief Reads the physical I/O port states.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @return The port bits.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readport(port) (((volatile uint16_t *)SIU.PGPDI)[port])
|
||||
|
||||
/**
|
||||
* @brief Reads the output latch.
|
||||
* @details The purpose of this function is to read back the latched output
|
||||
* value.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @return The latched logical states.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readlatch(port) (((volatile uint16_t *)SIU.PGPDO)[port])
|
||||
|
||||
/**
|
||||
* @brief Writes a bits mask on a I/O port.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] bits bits to be written on the specified port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writeport(port, bits) \
|
||||
(((volatile uint16_t *)SIU.PGPDO)[port] = (bits))
|
||||
|
||||
/**
|
||||
* @brief Reads a group of bits.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @return The group logical states.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readgroup(port, mask, offset) \
|
||||
_pal_lld_readgroup(port, mask, offset)
|
||||
|
||||
/**
|
||||
* @brief Writes a group of bits.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @param[in] bits bits to be written. Values exceeding the group width
|
||||
* are masked.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writegroup(port, mask, offset, bits) \
|
||||
_pal_lld_writegroup(port, mask, offset, bits)
|
||||
|
||||
/**
|
||||
* @brief Pads group mode setup.
|
||||
* @details This function programs a pads group belonging to the same port
|
||||
* with the specified mode.
|
||||
* @note Programming an unknown or unsupported mode is silently ignored.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @param[in] mode group mode
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setgroupmode(port, mask, offset, mode) \
|
||||
_pal_lld_setgroupmode(port, mask << offset, mode)
|
||||
|
||||
/**
|
||||
* @brief Reads a logical state from an I/O pad.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
* @return The logical state.
|
||||
* @retval PAL_LOW low logical state.
|
||||
* @retval PAL_HIGH high logical state.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readpad(port, pad) \
|
||||
(SIU.GPDI[((port) * 16) + (pad)].R)
|
||||
|
||||
/**
|
||||
* @brief Writes a logical state on an output pad.
|
||||
* @note This function is not meant to be invoked directly by the
|
||||
* application code.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
* @param[in] bit logical value, the value must be @p PAL_LOW or
|
||||
* @p PAL_HIGH
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writepad(port, pad, bit) \
|
||||
(SIU.GPDO[((port) * 16) + (pad)].R = (bit))
|
||||
|
||||
/**
|
||||
* @brief Sets a pad logical state to @p PAL_HIGH.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setpad(port, pad) \
|
||||
(SIU.GPDO[((port) * 16) + (pad)].R = 1)
|
||||
|
||||
/**
|
||||
* @brief Clears a pad logical state to @p PAL_LOW.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_clearpad(port, pad) \
|
||||
(SIU.GPDO[((port) * 16) + (pad)].R = 0)
|
||||
|
||||
/**
|
||||
* @brief Toggles a pad logical state.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_togglepad(port, pad) \
|
||||
(SIU.GPDO[((port) * 16) + (pad)].R = ~SIU.GPDO[((port) * 16) + (pad)].R)
|
||||
|
||||
/**
|
||||
* @brief Pad mode setup.
|
||||
* @details This function programs a pad with the specified mode.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
* @note Programming an unknown or unsupported mode is silently ignored.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
* @param[in] mode pad mode
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setpadmode(port, pad, mode)
|
||||
|
||||
extern const PALConfig pal_default_config;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _pal_lld_init(const PALConfig *config);
|
||||
ioportmask_t _pal_lld_readgroup(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
uint_fast8_t offset);
|
||||
void _pal_lld_writegroup(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
uint_fast8_t offset,
|
||||
ioportmask_t bits);
|
||||
void _pal_lld_setgroupmode(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
iomode_t mode);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_PAL */
|
||||
|
||||
#endif /* _PAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 SPC5xx/SIU_v1/pal_lld.c
|
||||
* @brief SPC5xx SIU low level driver code.
|
||||
*
|
||||
* @addtogroup PAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if defined(SPC5_SIU_SYSTEM_PINS)
|
||||
static const unsigned system_pins[] = {SPC5_SIU_SYSTEM_PINS};
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief SPC5xx I/O ports configuration.
|
||||
*
|
||||
* @param[in] config the STM32 ports configuration
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _pal_lld_init(const PALConfig *config) {
|
||||
unsigned i;
|
||||
|
||||
/* Initialize PCR registers for defined pads.*/
|
||||
i = 0;
|
||||
while (config->inits[i].pcr_value != 0) {
|
||||
SIU.GPDO[config->inits[i].pcr_index].R = config->inits[i].gpdo_value;
|
||||
SIU.PCR[config->inits[i].pcr_index].R = config->inits[i].pcr_value;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads a group of bits.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @return The group logical states.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
ioportmask_t _pal_lld_readgroup(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
uint_fast8_t offset) {
|
||||
|
||||
(void)port;
|
||||
(void)mask;
|
||||
(void)offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes a group of bits.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @param[in] bits bits to be written. Values exceeding the group width
|
||||
* are masked.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _pal_lld_writegroup(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
uint_fast8_t offset,
|
||||
ioportmask_t bits) {
|
||||
|
||||
(void)port;
|
||||
(void)mask;
|
||||
(void)offset;
|
||||
(void)bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pads mode setup.
|
||||
* @details This function programs a pads group belonging to the same port
|
||||
* with the specified mode.
|
||||
*
|
||||
* @param[in] port the port identifier
|
||||
* @param[in] mask the group mask
|
||||
* @param[in] mode the mode
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _pal_lld_setgroupmode(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
iomode_t mode) {
|
||||
unsigned pcr_index = (unsigned)(port * PAL_IOPORTS_WIDTH);
|
||||
ioportmask_t m1 = 0x8000;
|
||||
while (m1) {
|
||||
if (mask & m1)
|
||||
SIU.PCR[pcr_index].R = mode;
|
||||
m1 >>= 1;
|
||||
++pcr_index;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_PAL */
|
||||
|
||||
/** @} */
|
||||
+419
@@ -0,0 +1,419 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 SPC5xx/SIU_v1/pal_lld.h
|
||||
* @brief SPC5xx SIU low level driver header.
|
||||
*
|
||||
* @addtogroup PAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _PAL_LLD_H_
|
||||
#define _PAL_LLD_H_
|
||||
|
||||
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Unsupported modes and specific modes */
|
||||
/*===========================================================================*/
|
||||
|
||||
#undef PAL_MODE_RESET
|
||||
#undef PAL_MODE_UNCONNECTED
|
||||
#undef PAL_MODE_INPUT
|
||||
#undef PAL_MODE_INPUT_PULLUP
|
||||
#undef PAL_MODE_INPUT_PULLDOWN
|
||||
#undef PAL_MODE_INPUT_ANALOG
|
||||
#undef PAL_MODE_OUTPUT_PUSHPULL
|
||||
#undef PAL_MODE_OUTPUT_OPENDRAIN
|
||||
|
||||
/**
|
||||
* @name SIU-specific PAL modes
|
||||
* @{
|
||||
*/
|
||||
#define PAL_SPC5_PA_MASK (15U << 10)
|
||||
#define PAL_SPC5_PA(n) ((n) << 10)
|
||||
#define PAL_SPC5_OBE (1U << 9)
|
||||
#define PAL_SPC5_IBE (1U << 8)
|
||||
#define PAL_SPC5_DSC_10PF (0U << 6)
|
||||
#define PAL_SPC5_DSC_20PF (1U << 6)
|
||||
#define PAL_SPC5_DSC_30PF (2U << 6)
|
||||
#define PAL_SPC5_DSC_50PF (3U << 6)
|
||||
#define PAL_SPC5_ODE (1U << 5)
|
||||
#define PAL_SPC5_HYS (1U << 4)
|
||||
#define PAL_SPC5_WPE (1U << 1)
|
||||
#define PAL_SPC5_WPS (1U << 0)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Pads mode constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief After reset state.
|
||||
*/
|
||||
#define PAL_MODE_RESET 0
|
||||
|
||||
/**
|
||||
* @brief Safe state for <b>unconnected</b> pads.
|
||||
*/
|
||||
#define PAL_MODE_UNCONNECTED (PAL_SPC5_WPE | PAL_SPC5_WPS)
|
||||
|
||||
/**
|
||||
* @brief Regular input high-Z pad.
|
||||
*/
|
||||
#define PAL_MODE_INPUT (PAL_SPC5_IBE)
|
||||
|
||||
/**
|
||||
* @brief Input pad with weak pull up resistor.
|
||||
*/
|
||||
#define PAL_MODE_INPUT_PULLUP (PAL_SPC5_IBE |PAL_SPC5_WPE | \
|
||||
PAL_SPC5_WPS)
|
||||
|
||||
/**
|
||||
* @brief Input pad with weak pull down resistor.
|
||||
*/
|
||||
#define PAL_MODE_INPUT_PULLDOWN (PAL_SPC5_IBE |PAL_SPC5_WPE)
|
||||
|
||||
/**
|
||||
* @brief Push-pull output pad.
|
||||
*/
|
||||
#define PAL_MODE_OUTPUT_PUSHPULL (PAL_SPC5_IBE | PAL_SPC5_OBE)
|
||||
|
||||
/**
|
||||
* @brief Open-drain output pad.
|
||||
*/
|
||||
#define PAL_MODE_OUTPUT_OPENDRAIN (PAL_SPC5_IBE | PAL_SPC5_OBE | \
|
||||
PAL_SPC5_ODE)
|
||||
|
||||
/**
|
||||
* @brief Alternate "n" output pad.
|
||||
*/
|
||||
#define PAL_MODE_OUTPUT_ALTERNATE(n) (PAL_SPC5_IBE | PAL_SPC5_PA(n))
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I/O Ports Types and constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Width, in bits, of an I/O port.
|
||||
*/
|
||||
#define PAL_IOPORTS_WIDTH 16
|
||||
|
||||
/**
|
||||
* @brief Whole port mask.
|
||||
* @brief This macro specifies all the valid bits into a port.
|
||||
*/
|
||||
#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFF)
|
||||
|
||||
/**
|
||||
* @brief Digital I/O port sized unsigned type.
|
||||
*/
|
||||
typedef uint16_t ioportmask_t;
|
||||
|
||||
/**
|
||||
* @brief Port Identifier.
|
||||
* @details This type can be a scalar or some kind of pointer, do not make
|
||||
* any assumption about it, use the provided macros when populating
|
||||
* variables of this type.
|
||||
*/
|
||||
typedef uint32_t ioportid_t;
|
||||
|
||||
/**
|
||||
* @brief Digital I/O modes.
|
||||
*/
|
||||
typedef uint16_t iomode_t;
|
||||
|
||||
/**
|
||||
* @brief SIU/SIUL register initializer type.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t pcr_index;
|
||||
uint8_t gpdo_value;
|
||||
iomode_t pcr_value;
|
||||
} spc_siu_init_t;
|
||||
|
||||
/**
|
||||
* @brief Generic I/O ports static initializer.
|
||||
* @details An instance of this structure must be passed to @p palInit() at
|
||||
* system startup time in order to initialized the digital I/O
|
||||
* subsystem. This represents only the initial setup, specific pads
|
||||
* or whole ports can be reprogrammed at later time.
|
||||
* @note Implementations may extend this structure to contain more,
|
||||
* architecture dependent, fields.
|
||||
*/
|
||||
typedef struct {
|
||||
const spc_siu_init_t *inits;
|
||||
} PALConfig;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I/O Ports Identifiers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Port identifiers
|
||||
* @{
|
||||
*/
|
||||
#define PORT0 0
|
||||
#define PORT1 1
|
||||
#define PORT2 2
|
||||
#define PORT3 3
|
||||
#define PORT4 4
|
||||
#define PORT5 5
|
||||
#define PORT6 6
|
||||
#define PORT7 7
|
||||
#define PORT8 8
|
||||
#define PORT9 9
|
||||
#define PORT10 10
|
||||
#define PORT11 11
|
||||
#define PORT12 12
|
||||
#define PORT13 13
|
||||
#define PORT14 14
|
||||
#define PORT15 15
|
||||
#define PORT16 16
|
||||
#define PORT17 17
|
||||
#define PORT18 18
|
||||
#define PORT19 19
|
||||
#define PORT20 20
|
||||
#define PORT21 21
|
||||
#define PORT22 22
|
||||
#define PORT23 23
|
||||
#define PORT24 24
|
||||
#define PORT25 25
|
||||
#define PORT26 26
|
||||
#define PORT27 27
|
||||
#define PORT28 28
|
||||
#define PORT29 29
|
||||
#define PORT30 30
|
||||
#define PORT31 31
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Implementation, some of the following macros could be implemented as */
|
||||
/* functions, if so please put them in pal_lld.c. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Port bit helper macro.
|
||||
* @note Overrides the one in @p pal.h.
|
||||
*
|
||||
* @param[in] n bit position within the port
|
||||
*
|
||||
* @return The bit mask.
|
||||
*/
|
||||
#define PAL_PORT_BIT(n) ((ioportmask_t)(0x8000U >> (n)))
|
||||
|
||||
/**
|
||||
* @brief Low level PAL subsystem initialization.
|
||||
*
|
||||
* @param[in] config architecture-dependent ports configuration
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_init(config) _pal_lld_init(config)
|
||||
|
||||
#if SPC5_SIU_SUPPORTS_PORTS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Reads the physical I/O port states.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @return The port bits.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readport(port) (((volatile uint16_t *)SIU.PGPDI)[port])
|
||||
|
||||
/**
|
||||
* @brief Reads the output latch.
|
||||
* @details The purpose of this function is to read back the latched output
|
||||
* value.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @return The latched logical states.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readlatch(port) (((volatile uint16_t *)SIU.PGPDO)[port])
|
||||
|
||||
/**
|
||||
* @brief Writes a bits mask on a I/O port.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] bits bits to be written on the specified port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writeport(port, bits) \
|
||||
(((volatile uint16_t *)SIU.PGPDO)[port] = (bits))
|
||||
|
||||
/**
|
||||
* @brief Reads a group of bits.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @return The group logical states.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readgroup(port, mask, offset) \
|
||||
_pal_lld_readgroup(port, mask, offset)
|
||||
|
||||
/**
|
||||
* @brief Writes a group of bits.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @param[in] bits bits to be written. Values exceeding the group width
|
||||
* are masked.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writegroup(port, mask, offset, bits) \
|
||||
_pal_lld_writegroup(port, mask, offset, bits)
|
||||
|
||||
#endif /* SPC5_SIU_SUPPORTS_PORTS */
|
||||
|
||||
/**
|
||||
* @brief Pads group mode setup.
|
||||
* @details This function programs a pads group belonging to the same port
|
||||
* with the specified mode.
|
||||
* @note Programming an unknown or unsupported mode is silently ignored.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @param[in] mode group mode
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setgroupmode(port, mask, offset, mode) \
|
||||
_pal_lld_setgroupmode(port, mask << offset, mode)
|
||||
|
||||
/**
|
||||
* @brief Reads a logical state from an I/O pad.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
* @return The logical state.
|
||||
* @retval PAL_LOW low logical state.
|
||||
* @retval PAL_HIGH high logical state.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readpad(port, pad) \
|
||||
(SIU.GPDI[((port) * 16) + (pad)].R)
|
||||
|
||||
/**
|
||||
* @brief Writes a logical state on an output pad.
|
||||
* @note This function is not meant to be invoked directly by the
|
||||
* application code.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
* @param[in] bit logical value, the value must be @p PAL_LOW or
|
||||
* @p PAL_HIGH
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writepad(port, pad, bit) \
|
||||
(SIU.GPDO[((port) * 16) + (pad)].R = (bit))
|
||||
|
||||
/**
|
||||
* @brief Sets a pad logical state to @p PAL_HIGH.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setpad(port, pad) \
|
||||
(SIU.GPDO[((port) * 16) + (pad)].R = 1)
|
||||
|
||||
/**
|
||||
* @brief Clears a pad logical state to @p PAL_LOW.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_clearpad(port, pad) \
|
||||
(SIU.GPDO[((port) * 16) + (pad)].R = 0)
|
||||
|
||||
/**
|
||||
* @brief Toggles a pad logical state.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_togglepad(port, pad) \
|
||||
(SIU.GPDO[((port) * 16) + (pad)].R = ~SIU.GPDO[((port) * 16) + (pad)].R)
|
||||
|
||||
/**
|
||||
* @brief Pad mode setup.
|
||||
* @details This function programs a pad with the specified mode.
|
||||
* @note The @ref PAL provides a default software implementation of this
|
||||
* functionality, implement this function if can optimize it by using
|
||||
* special hardware functionalities or special coding.
|
||||
* @note Programming an unknown or unsupported mode is silently ignored.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
* @param[in] mode pad mode
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setpadmode(port, pad, mode)
|
||||
|
||||
extern const PALConfig pal_default_config;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _pal_lld_init(const PALConfig *config);
|
||||
ioportmask_t _pal_lld_readgroup(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
uint_fast8_t offset);
|
||||
void _pal_lld_writegroup(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
uint_fast8_t offset,
|
||||
ioportmask_t bits);
|
||||
void _pal_lld_setgroupmode(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
iomode_t mode);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_PAL */
|
||||
|
||||
#endif /* _PAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
+1389
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,612 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 eTimer_v1/icu_lld.h
|
||||
* @brief SPC5xx low level ICU driver header.
|
||||
*
|
||||
* @addtogroup ICU
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _ICU_LLD_H_
|
||||
#define _ICU_LLD_H_
|
||||
|
||||
#if HAL_USE_ICU || defined(__DOXYGEN__)
|
||||
|
||||
#include "spc5_etimer.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Mode options
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Skip first capture cycle.
|
||||
* @details If set to @p TRUE the first capture cycle is skipped.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(ICU_JUMP_FIRST_CAPTURE) || defined(__DOXYGEN__)
|
||||
#define ICU_SKIP_FIRST_CAPTURE FALSE
|
||||
#endif
|
||||
|
||||
#define SPC5_ETIMER_IP_BUS_CLOCK_DIVIDE_BY_1 0x18
|
||||
#define SPC5_ETIMER_IP_BUS_CLOCK_DIVIDE_BY_2 0x19
|
||||
#define SPC5_ETIMER_IP_BUS_CLOCK_DIVIDE_BY_4 0x1A
|
||||
#define SPC5_ETIMER_IP_BUS_CLOCK_DIVIDE_BY_8 0x1B
|
||||
#define SPC5_ETIMER_IP_BUS_CLOCK_DIVIDE_BY_16 0x1C
|
||||
#define SPC5_ETIMER_IP_BUS_CLOCK_DIVIDE_BY_32 0x1D
|
||||
#define SPC5_ETIMER_IP_BUS_CLOCK_DIVIDE_BY_64 0x1E
|
||||
#define SPC5_ETIMER_IP_BUS_CLOCK_DIVIDE_BY_128 0x1F
|
||||
|
||||
#define SPC5_ETIMER_COUNTER_0_INPUT_PIN 0U
|
||||
#define SPC5_ETIMER_COUNTER_1_INPUT_PIN 1U
|
||||
#define SPC5_ETIMER_COUNTER_2_INPUT_PIN 2U
|
||||
#define SPC5_ETIMER_COUNTER_3_INPUT_PIN 3U
|
||||
#define SPC5_ETIMER_COUNTER_4_INPUT_PIN 4U
|
||||
#define SPC5_ETIMER_COUNTER_5_INPUT_PIN 5U
|
||||
|
||||
#define SPC5_ETIMER_CNTMODE_NO_OPERATION 0U
|
||||
#define SPC5_ETIMER_CNTMODE_RE 1U
|
||||
#define SPC5_ETIMER_CNTMODE_RFE 2U
|
||||
#define SPC5_ETIMER_CNTMODE_RFE_SIHA 3U
|
||||
#define SPC5_ETIMER_CNTMODE_QUADRATURE 4U
|
||||
#define SPC5_ETIMER_CNTMODE_RE_SSSD 5U
|
||||
#define SPC5_ETIMER_CNTMODE_ESS_TRIGGER 6U
|
||||
#define SPC5_ETIMER_CNTMODE_CASCADE 7U
|
||||
|
||||
#define SPC5_ETIMER_CPT1MODE_DISABLED 0U
|
||||
#define SPC5_ETIMER_CPT1MODE_FALLING_EDGE 1U
|
||||
#define SPC5_ETIMER_CPT1MODE_RISING_EDGE 2U
|
||||
#define SPC5_ETIMER_CPT1MODE_ANY_EDGE 3U
|
||||
|
||||
#define SPC5_ETIMER_CPT2MODE_DISABLED 0U
|
||||
#define SPC5_ETIMER_CPT2MODE_FALLING_EDGE 1U
|
||||
#define SPC5_ETIMER_CPT2MODE_RISING_EDGE 2U
|
||||
#define SPC5_ETIMER_CPT2MODE_ANY_EDGE 3U
|
||||
|
||||
#define SPC5_ETIMER_ROC_DO_NOT_RELOAD 0U
|
||||
#define SPC5_ETIMER_ROC_REL_ON_CAP1 1U
|
||||
#define SPC5_ETIMER_ROC_REL_ON_CAP2 2U
|
||||
#define SPC5_ETIMER_ROC_REL_ON_CAP1_CAP2 3U
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief ICUD1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD1 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD0) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD0 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD2 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD2 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD1) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD1 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD3 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD3 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD2) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD2 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD4 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD4 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD3) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD3 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD5 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD5 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD4) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD4 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD6 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD6 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD5) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD5 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief eTimer0 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_ETIMER0_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_ETIMER0_PRIORITY 7
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief eTIMER0 peripheral configuration when started.
|
||||
* @note The default configuration is 1 (always run) in run mode and
|
||||
* 2 (only halt) in low power mode. The defaults of the run modes
|
||||
* are defined in @p hal_lld.h.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_ETIMER0_START_PCTL) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_ETIMER0_START_PCTL (SPC5_ME_PCTL_RUN(1) | \
|
||||
SPC5_ME_PCTL_LP(2))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief eTIMER0 peripheral configuration when stopped.
|
||||
* @note The default configuration is 0 (never run) in run mode and
|
||||
* 0 (never run) in low power mode. The defaults of the run modes
|
||||
* are defined in @p hal_lld.h.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_ETIMER0_STOP_PCTL) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_ETIMER0_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \
|
||||
SPC5_ME_PCTL_LP(0))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD6 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD6 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD6) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD6 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD7 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD7 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD7) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD7 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD8 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD8 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD8) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD8 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD9 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD9 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD9) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD9 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD10 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD10 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD10) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD10 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD11 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD11 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD11) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD11 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief eTimer1 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_ETIMER1_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_ETIMER1_PRIORITY 7
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief eTIMER1 peripheral configuration when started.
|
||||
* @note The default configuration is 1 (always run) in run mode and
|
||||
* 2 (only halt) in low power mode. The defaults of the run modes
|
||||
* are defined in @p hal_lld.h.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_ETIMER1_START_PCTL) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_ETIMER1_START_PCTL (SPC5_ME_PCTL_RUN(1) | \
|
||||
SPC5_ME_PCTL_LP(2))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief eTIMER1 peripheral configuration when stopped.
|
||||
* @note The default configuration is 0 (never run) in run mode and
|
||||
* 0 (never run) in low power mode. The defaults of the run modes
|
||||
* are defined in @p hal_lld.h.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_ETIMER1_STOP_PCTL) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_ETIMER1_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \
|
||||
SPC5_ME_PCTL_LP(0))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD13 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD13 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD12) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD12 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD14 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD14 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD13) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD13 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD15 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD15 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD14) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD14 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD16 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD16 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD15) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD15 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD17 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD17 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD16) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD16 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ICUD18 driver enable switch.
|
||||
* @details If set to @p TRUE the support for ICUD18 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_USE_SMOD17) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_USE_SMOD17 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief eTimer2 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_ETIMER2_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_ETIMER2_PRIORITY 7
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief eTIMER2 peripheral configuration when started.
|
||||
* @note The default configuration is 1 (always run) in run mode and
|
||||
* 2 (only halt) in low power mode. The defaults of the run modes
|
||||
* are defined in @p hal_lld.h.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_ETIMER2_START_PCTL) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_ETIMER2_START_PCTL (SPC5_ME_PCTL_RUN(1) | \
|
||||
SPC5_ME_PCTL_LP(2))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief eTIMER2 peripheral configuration when stopped.
|
||||
* @note The default configuration is 0 (never run) in run mode and
|
||||
* 0 (never run) in low power mode. The defaults of the run modes
|
||||
* are defined in @p hal_lld.h.
|
||||
*/
|
||||
#if !defined(SPC5_ICU_ETIMER2_STOP_PCTL) || defined(__DOXYGEN__)
|
||||
#define SPC5_ICU_ETIMER2_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \
|
||||
SPC5_ME_PCTL_LP(0))
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define SPC5_ICU_USE_ETIMER0 (SPC5_ICU_USE_SMOD0 || \
|
||||
SPC5_ICU_USE_SMOD1 || \
|
||||
SPC5_ICU_USE_SMOD2 || \
|
||||
SPC5_ICU_USE_SMOD3 || \
|
||||
SPC5_ICU_USE_SMOD4 || \
|
||||
SPC5_ICU_USE_SMOD5)
|
||||
|
||||
#define SPC5_ICU_USE_ETIMER1 (SPC5_ICU_USE_SMOD6 || \
|
||||
SPC5_ICU_USE_SMOD7 || \
|
||||
SPC5_ICU_USE_SMOD8 || \
|
||||
SPC5_ICU_USE_SMOD9 || \
|
||||
SPC5_ICU_USE_SMOD10 || \
|
||||
SPC5_ICU_USE_SMOD11)
|
||||
|
||||
#define SPC5_ICU_USE_ETIMER2 (SPC5_ICU_USE_SMOD12 || \
|
||||
SPC5_ICU_USE_SMOD13 || \
|
||||
SPC5_ICU_USE_SMOD14 || \
|
||||
SPC5_ICU_USE_SMOD15 || \
|
||||
SPC5_ICU_USE_SMOD16 || \
|
||||
SPC5_ICU_USE_SMOD17)
|
||||
|
||||
#if !SPC5_HAS_ETIMER0 && SPC5_ICU_USE_ETIMER0
|
||||
#error "ETIMER0 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if !SPC5_HAS_ETIMER1 && SPC5_ICU_USE_ETIMER1
|
||||
#error "ETIMER1 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if !SPC5_HAS_ETIMER2 && SPC5_ICU_USE_ETIMER2
|
||||
#error "ETIMER2 not present in the selected device"
|
||||
#endif
|
||||
|
||||
#if !SPC5_ICU_USE_ETIMER0 && !SPC5_ICU_USE_ETIMER1 && !SPC5_ICU_USE_ETIMER2
|
||||
#error "ICU driver activated but no SMOD peripheral assigned"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief ICU driver mode.
|
||||
*/
|
||||
typedef enum {
|
||||
ICU_INPUT_ACTIVE_HIGH = 0, /**< Trigger on rising edge. */
|
||||
ICU_INPUT_ACTIVE_LOW = 1, /**< Trigger on falling edge. */
|
||||
} icumode_t;
|
||||
|
||||
/**
|
||||
* @brief ICU frequency type.
|
||||
*/
|
||||
typedef uint32_t icufreq_t;
|
||||
|
||||
/**
|
||||
* @brief ICU channel.
|
||||
*/
|
||||
typedef enum {
|
||||
ICU_CHANNEL_1 = 0, /**< Use SMODxCH1. */
|
||||
ICU_CHANNEL_2 = 1, /**< Use SMODxCH2. */
|
||||
ICU_CHANNEL_3 = 2, /**< Use SMODxCH3. */
|
||||
ICU_CHANNEL_4 = 3, /**< Use SMODxCH4. */
|
||||
ICU_CHANNEL_5 = 4, /**< Use SMODxCH5. */
|
||||
ICU_CHANNEL_6 = 5, /**< Use SMODxCH6. */
|
||||
} icuchannel_t;
|
||||
|
||||
/**
|
||||
* @brief ICU counter type.
|
||||
*/
|
||||
typedef uint16_t icucnt_t;
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note It could be empty on some architectures.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Driver mode.
|
||||
*/
|
||||
icumode_t mode;
|
||||
/**
|
||||
* @brief Timer clock in Hz.
|
||||
* @note The low level can use assertions in order to catch invalid
|
||||
* frequency specifications.
|
||||
*/
|
||||
icufreq_t frequency;
|
||||
/**
|
||||
* @brief Callback for pulse width measurement.
|
||||
*/
|
||||
icucallback_t width_cb;
|
||||
/**
|
||||
* @brief Callback for cycle period measurement.
|
||||
*/
|
||||
icucallback_t period_cb;
|
||||
/**
|
||||
* @brief Callback for timer overflow.
|
||||
*/
|
||||
icucallback_t overflow_cb;
|
||||
/* End of the mandatory fields.*/
|
||||
} ICUConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing an ICU driver.
|
||||
*/
|
||||
struct ICUDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
icustate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const ICUConfig *config;
|
||||
#if defined(ICU_DRIVER_EXT_FIELDS)
|
||||
ICU_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Clock value for this unit.
|
||||
*/
|
||||
uint32_t clock;
|
||||
/**
|
||||
* @brief eTimer submodule number.
|
||||
*/
|
||||
uint32_t smod_number;
|
||||
/**
|
||||
* @brief Pointer to the eTimerx registers block.
|
||||
*/
|
||||
volatile struct spc5_etimer *etimerp;
|
||||
/**
|
||||
* @brief CCR register used for width capture.
|
||||
*/
|
||||
volatile vuint16_t *wccrp;
|
||||
/**
|
||||
* @brief CCR register used for period capture.
|
||||
*/
|
||||
volatile vuint16_t *pccrp;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Returns the width of the latest pulse.
|
||||
* @details The pulse width is defined as number of ticks between the start
|
||||
* edge and the stop edge.
|
||||
*
|
||||
* @param[in] icup pointer to the @p ICUDriver object
|
||||
* @return The number of ticks.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define icu_lld_get_width(icup) (*((icup)->wccrp) + 1)
|
||||
|
||||
/**
|
||||
* @brief Returns the width of the latest cycle.
|
||||
* @details The cycle width is defined as number of ticks between a start
|
||||
* edge and the next start edge.
|
||||
*
|
||||
* @param[in] icup pointer to the @p ICUDriver object
|
||||
* @return The number of ticks.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define icu_lld_get_period(icup) (*((icup)->pccrp) + 1)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if SPC5_ICU_USE_SMOD0 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD1;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD1 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD2;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD2 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD3;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD3 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD4;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD4 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD5;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD5 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD6;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD6 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD7;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD7 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD8;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD8 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD9;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD9 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD10;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD10 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD11;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD11 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD12;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD12 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD13;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD13 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD14;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD14 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD15;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD15 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD16;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD16 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD17;
|
||||
#endif
|
||||
|
||||
#if SPC5_ICU_USE_SMOD17 && !defined(__DOXYGEN__)
|
||||
extern ICUDriver ICUD18;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void icu_lld_init(void);
|
||||
void icu_lld_start(ICUDriver *icup);
|
||||
void icu_lld_stop(ICUDriver *icup);
|
||||
void icu_lld_enable(ICUDriver *icup);
|
||||
void icu_lld_disable(ICUDriver *icup);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_ICU */
|
||||
|
||||
#endif /* _ICU_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
SPC5 HAL - Copyright (C) 2013 STMicroelectronics
|
||||
|
||||
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 eTimer_v1/etimer.h
|
||||
* @brief SPC5xx eTimer header file.
|
||||
*
|
||||
* @addtogroup ICU
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _ETIMER_H_
|
||||
#define _ETIMER_H_
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief SPC5 FlexPWM registers block.
|
||||
* @note Redefined from the SPC5 headers because the non uniform
|
||||
* declaration of the SubModules registers among the various
|
||||
* sub-families.
|
||||
*/
|
||||
struct spc5_etimer_submodule {
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t COMP1 :16;
|
||||
} B;
|
||||
} COMP1; /* Compare Register 1 */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t COMP2 :16;
|
||||
} B;
|
||||
} COMP2; /* Compare Register 2 */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CAPT1 :16;
|
||||
} B;
|
||||
} CAPT1; /* Capture Register 1 */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CAPT2 :16;
|
||||
} B;
|
||||
} CAPT2; /* Capture Register 2 */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t LOAD :16;
|
||||
} B;
|
||||
} LOAD; /* Load Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t HOLD :16;
|
||||
} B;
|
||||
} HOLD; /* Hold Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CNTR :16;
|
||||
} B;
|
||||
} CNTR; /* Counter Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CNTMODE :3;
|
||||
vuint16_t PRISRC :5;
|
||||
vuint16_t ONCE :1;
|
||||
vuint16_t LENGTH :1;
|
||||
vuint16_t DIR :1;
|
||||
vuint16_t SECSRC :5;
|
||||
} B;
|
||||
} CTRL; /* Control Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t OEN :1;
|
||||
vuint16_t RDNT :1;
|
||||
vuint16_t INPUT :1;
|
||||
vuint16_t VAL :1;
|
||||
vuint16_t FORCE :1;
|
||||
vuint16_t COFRC :1;
|
||||
vuint16_t COINIT :2;
|
||||
vuint16_t SIPS :1;
|
||||
vuint16_t PIPS :1;
|
||||
vuint16_t OPS :1;
|
||||
vuint16_t MSTR :1;
|
||||
vuint16_t OUTMODE :4;
|
||||
} B;
|
||||
} CTRL2; /* Control Register 2 */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t STPEN :1;
|
||||
vuint16_t ROC :2;
|
||||
vuint16_t FMODE :1;
|
||||
vuint16_t FDIS :4;
|
||||
vuint16_t C2FCNT :3;
|
||||
vuint16_t C1FCNT :3;
|
||||
vuint16_t DBGEN :2;
|
||||
} B;
|
||||
} CTRL3; /* Control Register 3 */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :6;
|
||||
vuint16_t WDF :1;
|
||||
vuint16_t RCF :1;
|
||||
vuint16_t ICF2 :1;
|
||||
vuint16_t ICF1 :1;
|
||||
vuint16_t IEHF :1;
|
||||
vuint16_t IELF :1;
|
||||
vuint16_t TOF :1;
|
||||
vuint16_t TCF2 :1;
|
||||
vuint16_t TCF1 :1;
|
||||
vuint16_t TCF :1;
|
||||
} B;
|
||||
} STS; /* Status Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t ICF2DE :1;
|
||||
vuint16_t ICF1DE :1;
|
||||
vuint16_t CMPLD2DE :1;
|
||||
vuint16_t CMPLD1DE :1;
|
||||
vuint16_t :2;
|
||||
vuint16_t WDFIE :1;
|
||||
vuint16_t RCFIE :1;
|
||||
vuint16_t ICF2IE :1;
|
||||
vuint16_t ICF1IE :1;
|
||||
vuint16_t IEHFIE :1;
|
||||
vuint16_t IELFIE :1;
|
||||
vuint16_t TOFIE :1;
|
||||
vuint16_t TCF2IE :1;
|
||||
vuint16_t TCF1IE :1;
|
||||
vuint16_t TCFIE :1;
|
||||
} B;
|
||||
} INTDMA; /* Interrupt and DMA Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CMPLD1 :16;
|
||||
} B;
|
||||
} CMPLD1; /* Compare Load Register 1 */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CMPLD2 :16;
|
||||
} B;
|
||||
} CMPLD2; /* Compare Load Register 2 */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t CLC2 :3;
|
||||
vuint16_t CLC1 :3;
|
||||
vuint16_t CMPMODE :2;
|
||||
vuint16_t CPT2MODE :2;
|
||||
vuint16_t CPT1MODE :2;
|
||||
vuint16_t CFWM :2;
|
||||
vuint16_t ONESHOT :1;
|
||||
vuint16_t ARM :1;
|
||||
} B;
|
||||
} CCCTRL; /* Compare and Capture Control Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :5;
|
||||
vuint16_t FILTCNT :3;
|
||||
vuint16_t FILTPER :8;
|
||||
} B;
|
||||
} FILT; /* Input Filter Register */
|
||||
|
||||
};
|
||||
/* end of ETIMER_CHANNEL_tag */
|
||||
|
||||
struct spc5_etimer {
|
||||
|
||||
struct spc5_etimer_submodule CHANNEL[8];
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t WDTOL :16;
|
||||
} B;
|
||||
} WDTOL; /* Watchdog Time-out Low Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t WDTOH :16;
|
||||
} B;
|
||||
} WDTOH; /* Watchdog Time-out High Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :3;
|
||||
vuint16_t FTEST :1;
|
||||
vuint16_t FIE :4;
|
||||
vuint16_t :4;
|
||||
vuint16_t FLVL :4;
|
||||
} B;
|
||||
} FCTRL; /* Fault Control Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :4;
|
||||
vuint16_t FFPIN :4;
|
||||
vuint16_t :4;
|
||||
vuint16_t FFLAG :4;
|
||||
} B;
|
||||
} FSTS; /* Fault Status Register */
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :5;
|
||||
vuint16_t FFILTCNT :3;
|
||||
vuint16_t FFILTPER :8;
|
||||
} B;
|
||||
} FFILT; /* Fault Filter Register */
|
||||
|
||||
int16_t ETIMER_reserved1;
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :8;
|
||||
vuint16_t ENBL :8;
|
||||
} B;
|
||||
} ENBL; /* Channel Enable Register */
|
||||
|
||||
int16_t ETIMER_reserved2;
|
||||
|
||||
union {
|
||||
vuint16_t R;
|
||||
struct {
|
||||
vuint16_t :11;
|
||||
vuint16_t DREQ :5;
|
||||
} B;
|
||||
} DREQ[4]; /* DMA Request 0->3 Select Register */
|
||||
|
||||
};
|
||||
/* end of ETIMER_tag */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name FlexPWM units references
|
||||
* @{
|
||||
*/
|
||||
#if SPC5_HAS_ETIMER0
|
||||
#define SPC5_ETIMER_0 (*(volatile struct spc5_etimer *)0xFFE18000UL)
|
||||
#endif
|
||||
|
||||
#if SPC5_HAS_ETIMER1
|
||||
#define SPC5_ETIMER_1 (*(volatile struct spc5_etimer *)0xFFE1C000UL)
|
||||
#endif
|
||||
|
||||
#if SPC5_HAS_ETIMER2
|
||||
#define SPC5_ETIMER_2 (*(volatile struct spc5_etimer *)0xFFE20000UL)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#endif /* _FLEXPWM_H_ */
|
||||
|
||||
/** @} */
|
||||
Reference in New Issue
Block a user