move mcu cmsis file to /mcu
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,456 @@
|
||||
/**********************************************************************
|
||||
* $Id$ LCDTerm.c 2011-12-06
|
||||
*//**
|
||||
* @file LCDTerm.c
|
||||
* @brief This is a library that can be used to display text on the LCD of Hitex 1800 board
|
||||
* @version 1.0
|
||||
* @date 06. Dec. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
#if defined(HITEX_LCD_TERM)
|
||||
#include "lpc43xx_ssp.h"
|
||||
#include "lpc43xx_scu.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
//#include "lpc43xx_libcfg.h"
|
||||
#include "debug_frmwrk.h"
|
||||
#include "lpc43xx_gpio.h"
|
||||
#include "LCDTerm.h"
|
||||
|
||||
|
||||
/************************** PRIVATE DEFINTIONS ************************/
|
||||
/** Max buffer length */
|
||||
#define BUFFER_SIZE 0x40
|
||||
#define FONT_OFFSET 32
|
||||
#define FONT_WIDTH 5
|
||||
#define CHARS_PER_ROW 25
|
||||
#define NO_OF_ROWS 4
|
||||
#define MAX_CHARS_DISPLAYED CHARS_PER_ROW * NO_OF_ROWS
|
||||
#define ROW_PIXELS 128
|
||||
#define COL_PIXELS 8
|
||||
#define Highlight 1
|
||||
#define NoHighlight 0
|
||||
|
||||
/************************** PRIVATE VARIABLES *************************/
|
||||
|
||||
// SSP Configuration structure variable
|
||||
SSP_CFG_Type SSP_ConfigStruct;
|
||||
|
||||
// Tx buffer
|
||||
uint8_t Tx_Buf[BUFFER_SIZE];
|
||||
|
||||
// Rx buffer
|
||||
uint8_t Rx_Buf[BUFFER_SIZE];
|
||||
|
||||
//Character indexes
|
||||
uint8_t Char_Index[256];
|
||||
uint8_t Highlight_Value[256];
|
||||
|
||||
char Chars_Displayed[88];
|
||||
uint8_t Number_of_Chars = 0, Start_Index = 0, Current_Index = 0;
|
||||
|
||||
/***************************IMPORT VARIABLES**************************/
|
||||
extern const UNS_16 x5x7_bits [];
|
||||
|
||||
/************************** PRIVATE FUNCTIONS *************************/
|
||||
void delay(unsigned int n)
|
||||
{
|
||||
volatile unsigned int i,j;
|
||||
for (i=0;i<n;i++)
|
||||
for (j=0;j<400;j++)
|
||||
{;}
|
||||
}
|
||||
|
||||
void data_out(unsigned char i, SSP_DATA_SETUP_Type *xferConfig);
|
||||
void comm_out(unsigned char j, SSP_DATA_SETUP_Type *xferConfig);
|
||||
void init_LCD(SSP_DATA_SETUP_Type *xferConfig);
|
||||
void Init_Indexes(void);
|
||||
|
||||
/*-------------------------PRIVATE FUNCTIONS------------------------------*/
|
||||
|
||||
/*-------------------------SET UP FUNCTION------------------------------*/
|
||||
/*********************************************************************//**
|
||||
* @brief Main set up function
|
||||
* @param[in] None
|
||||
* @return SSP_DATA_SETUP_Type
|
||||
**********************************************************************/
|
||||
SSP_DATA_SETUP_Type *InitLCDTerm(void)
|
||||
{
|
||||
// char * lcd_string = logo;
|
||||
unsigned char page = 0xB0;
|
||||
int i = 0, j = 0;
|
||||
static SSP_DATA_SETUP_Type xferConfig;
|
||||
|
||||
Init_Indexes();
|
||||
|
||||
/* Configure SSP0 pins*/
|
||||
// Configure all the pins of the LCD
|
||||
scu_pinmux(0x7,4,MD_PUP,FUNC0); // P7.4 connected to GPIO = SPI_CSI
|
||||
scu_pinmux(0xA,2,MD_PUP,FUNC0); // PA.2 connected to GPIO = LCD_RST
|
||||
scu_pinmux(0xA,3,MD_PUP,FUNC0); // PA.3 connected to GPIO = LCD_A0
|
||||
scu_pinmux(0xF,3,(MD_PUP | MD_EHS),FUNC2);
|
||||
scu_pinmux(0xF,3,(MD_PUP | MD_EHS),FUNC2);
|
||||
|
||||
//Set the directions
|
||||
GPIO_SetDir(0x3,(1<<12), 1);
|
||||
GPIO_SetDir(0x4,(1<<9), 1);
|
||||
GPIO_SetDir(0x4,(1<<10), 1);
|
||||
|
||||
|
||||
//Reset lcd
|
||||
GPIO_ClearValue(3,(1<<12)); //set CS
|
||||
GPIO_SetValue(4,(1<<9));
|
||||
delay(100);
|
||||
GPIO_ClearValue(4,(1<<9));
|
||||
delay(100);
|
||||
GPIO_SetValue(4,(1<<9));
|
||||
delay(100);
|
||||
GPIO_SetValue(3,(1<<12)); //set CS
|
||||
GPIO_SetValue(4,(1<<10)); //set A0
|
||||
delay(100);
|
||||
|
||||
|
||||
// initialize SSP configuration structure to default
|
||||
SSP_ConfigStructInit(&SSP_ConfigStruct);
|
||||
|
||||
//Note that the LCD does not work as expected above 35-40Mb/s
|
||||
//Setting the speed to 10 Mb/s
|
||||
SSP_ConfigStruct.ClockRate = 10000000;
|
||||
|
||||
// Initialize SSP peripheral with parameter given in structure above
|
||||
SSP_Init(LPC_SSP0, &SSP_ConfigStruct);
|
||||
|
||||
// Enable SSP peripheral
|
||||
SSP_Cmd(LPC_SSP0, ENABLE);
|
||||
delay(100);
|
||||
delay(100);
|
||||
xferConfig.length = 1;
|
||||
init_LCD(&xferConfig);
|
||||
|
||||
//wait for the lcd to reboot
|
||||
delay(100);
|
||||
delay(100);
|
||||
delay(100);
|
||||
delay(100);
|
||||
delay(100);
|
||||
|
||||
xferConfig.tx_data = Tx_Buf;
|
||||
xferConfig.rx_data = Rx_Buf;
|
||||
|
||||
comm_out(0xAE, &xferConfig); //Display OFF
|
||||
comm_out(0x40, &xferConfig); //Display start address + 0x40
|
||||
page = 0xB0;
|
||||
|
||||
for(i=0;i<8;i++){ //32pixel display / 8 pixels per page = 4 pages
|
||||
comm_out(page, &xferConfig); //send page address
|
||||
comm_out(0x10, &xferConfig); //column address upper 4 bits + 0x10
|
||||
comm_out(0x00, &xferConfig); //column address lower 4 bits + 0x00
|
||||
for(j=0;j<131;j++){ //128 columns wide
|
||||
data_out(0x00, &xferConfig);
|
||||
}
|
||||
page++; //after 128 columns, go to next page
|
||||
}
|
||||
comm_out(0xAF, &xferConfig);
|
||||
|
||||
comm_out(0xAE, &xferConfig); //Display OFF
|
||||
comm_out(0x40, &xferConfig); //Display start address + 0x40
|
||||
comm_out(0xB0, &xferConfig);
|
||||
comm_out(0x10, &xferConfig); //column address upper 4 bits + 0x10
|
||||
comm_out(0x00, &xferConfig); //column address lower 4 bits + 0x00
|
||||
comm_out(0xAF, &xferConfig);
|
||||
//delay(100);
|
||||
return &xferConfig;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
void data_out(unsigned char i, SSP_DATA_SETUP_Type *xferConfig) //Data Output Serial Interface
|
||||
{
|
||||
//unsigned int n;
|
||||
//CS = 0; //Chip Select = Active
|
||||
GPIO_ClearValue(3,(1<<12));
|
||||
//A0 = 1 = Data
|
||||
//GPIO_SetValue(4,(1<<10));
|
||||
//delay(1);
|
||||
|
||||
Tx_Buf[0] = i;
|
||||
xferConfig->tx_data = Tx_Buf;
|
||||
SSP_ReadWrite(LPC_SSP0, xferConfig, SSP_TRANSFER_POLLING);
|
||||
|
||||
//CS = 1; //after 1 byte, Chip Select = inactive
|
||||
delay(1);
|
||||
GPIO_SetValue(3,(1<<12));
|
||||
}
|
||||
|
||||
void comm_out(unsigned char j, SSP_DATA_SETUP_Type *xferConfig) //Command Output Serial Interface
|
||||
{
|
||||
//unsigned int n;
|
||||
//CS = 0; //Chip Select = Active
|
||||
//GPIO_ClearValue(3,(1<<12));
|
||||
//A0 = 0;
|
||||
GPIO_ClearValue(4,(1<<10));
|
||||
//delay(1);
|
||||
|
||||
Tx_Buf[0] = j;
|
||||
xferConfig->tx_data = Tx_Buf;
|
||||
SSP_ReadWrite(LPC_SSP0, xferConfig, SSP_TRANSFER_POLLING);
|
||||
|
||||
//CS = 1; //after 1 byte, Chip Select = inactive
|
||||
delay(1);
|
||||
GPIO_SetValue(3,(1<<12));
|
||||
}
|
||||
|
||||
void init_LCD(SSP_DATA_SETUP_Type *xferConfig)
|
||||
{
|
||||
comm_out(0xA0, xferConfig); //RAM->SEG output = normal
|
||||
comm_out(0xAE, xferConfig); //Display OFF
|
||||
comm_out(0xC8, xferConfig); //COM scan direction = normal
|
||||
comm_out(0xA2, xferConfig); //1/9 bias
|
||||
|
||||
comm_out(0x2F, xferConfig); //power control set
|
||||
comm_out(0x20, xferConfig); //resistor ratio set
|
||||
comm_out(0x81, xferConfig); //Electronic volume command (set contrast)
|
||||
comm_out(0x1F, xferConfig); //Electronic volume value (contrast value)
|
||||
comm_out(0xAF, xferConfig);
|
||||
delay(1);
|
||||
comm_out(0xAE, xferConfig);
|
||||
comm_out(0x21, xferConfig);
|
||||
comm_out(0xAF, xferConfig);
|
||||
|
||||
delay(100);
|
||||
}
|
||||
|
||||
void Init_Indexes() {
|
||||
uint8_t i = 0, index = '!';
|
||||
for(i = 1; i <= 93; i++, index++) {
|
||||
Char_Index[index] = i;
|
||||
}
|
||||
|
||||
Char_Index[' '] = 0;
|
||||
}
|
||||
|
||||
|
||||
void WriteChar(char ch, SSP_DATA_SETUP_Type *xferConfig, uint8_t nHighlight)
|
||||
{
|
||||
uint8_t Col, i, index, temp;
|
||||
uint8_t lcd_Values[5], needRefresh = 0, Chars_Displayed_c = 0;
|
||||
UNS_16 raw_value[7], raw, DisplayStart,DisplayEnd, Page_No;
|
||||
|
||||
comm_out(0xAE, xferConfig);
|
||||
|
||||
//Update the array of characters that are displayed right now.
|
||||
if(ch == '\b' || ch == '\r') {
|
||||
comm_out(0xAF, xferConfig);
|
||||
return;
|
||||
}
|
||||
if(ch != '\n') {
|
||||
if(Number_of_Chars < MAX_CHARS_DISPLAYED) {
|
||||
Chars_Displayed[Current_Index] = ch;
|
||||
Current_Index++;
|
||||
Number_of_Chars++;
|
||||
} else {
|
||||
Start_Index++;
|
||||
if(Start_Index >= MAX_CHARS_DISPLAYED) {
|
||||
Current_Index = Start_Index - 1;
|
||||
Start_Index = 0;
|
||||
} else {
|
||||
Current_Index = Start_Index - 1;
|
||||
}
|
||||
Chars_Displayed[Current_Index] = ch;
|
||||
Current_Index++;
|
||||
}
|
||||
|
||||
if(nHighlight) {
|
||||
Highlight_Value[Current_Index-1] = Highlight;
|
||||
} else {
|
||||
Highlight_Value[Current_Index-1] = NoHighlight;
|
||||
}
|
||||
}
|
||||
|
||||
//Code to handle the next line character.
|
||||
else {
|
||||
index = (((Current_Index) + CHARS_PER_ROW) % CHARS_PER_ROW); //1 index
|
||||
index = CHARS_PER_ROW - index;
|
||||
ch = ' ';
|
||||
for(temp = 0; temp < index; temp++) {
|
||||
|
||||
if(Number_of_Chars < MAX_CHARS_DISPLAYED) {
|
||||
Chars_Displayed[Current_Index] = ch;
|
||||
Current_Index++;
|
||||
Number_of_Chars++;
|
||||
} else {
|
||||
Start_Index++;
|
||||
if(Start_Index >= MAX_CHARS_DISPLAYED) {
|
||||
Current_Index = Start_Index - 1;
|
||||
Start_Index = 0;
|
||||
} else {
|
||||
Current_Index = Start_Index - 1;
|
||||
}
|
||||
Chars_Displayed[Current_Index] = ch;
|
||||
Current_Index++;
|
||||
}
|
||||
//Chars_Displayed[i] = ' ';
|
||||
i++;
|
||||
for(Col = 0; Col < FONT_WIDTH; Col++)
|
||||
data_out(0, xferConfig);
|
||||
//Start_Index++;
|
||||
}
|
||||
|
||||
//if(Number_of_Chars >= MAX_CHARS_DISPLAYED) {
|
||||
if(!(Number_of_Chars < (MAX_CHARS_DISPLAYED + 1))) {
|
||||
//Send the scrollbar
|
||||
data_out(0xFF, xferConfig);
|
||||
data_out(0x81, xferConfig);
|
||||
data_out(0xFF, xferConfig);
|
||||
}
|
||||
//Current_Index = i;
|
||||
ch = '\n';
|
||||
}
|
||||
|
||||
//Find if the whole screen needs to be updated.
|
||||
if(!(Number_of_Chars < (MAX_CHARS_DISPLAYED + 1))) {
|
||||
if(((Start_Index + CHARS_PER_ROW) % CHARS_PER_ROW) == 1) {
|
||||
needRefresh = 1;
|
||||
} else {
|
||||
needRefresh = 0;
|
||||
}
|
||||
DisplayStart = Start_Index + CHARS_PER_ROW;
|
||||
DisplayStart = DisplayStart - (DisplayStart % CHARS_PER_ROW);
|
||||
if(DisplayStart >= MAX_CHARS_DISPLAYED) {
|
||||
DisplayStart -= MAX_CHARS_DISPLAYED;
|
||||
}
|
||||
} else {
|
||||
DisplayStart = Start_Index;
|
||||
}
|
||||
DisplayEnd = (Current_Index - 1);
|
||||
|
||||
if(needRefresh == 0) {
|
||||
DisplayStart = DisplayEnd;
|
||||
}
|
||||
|
||||
Page_No = ((Number_of_Chars-1) / CHARS_PER_ROW);
|
||||
Page_No |= 0xB0;
|
||||
|
||||
if((Page_No == (0xB0 + NO_OF_ROWS)) && needRefresh == 1) {
|
||||
Page_No = 0xB0;
|
||||
comm_out(Page_No, xferConfig); //send page address
|
||||
comm_out(0x10, xferConfig); //column address upper 4 bits + 0x10
|
||||
comm_out(0x00, xferConfig); //column address lower 4 bits + 0x00
|
||||
} else if ((((Number_of_Chars-1) % CHARS_PER_ROW) == 0) && (Page_No != 0xB4)) {
|
||||
comm_out(Page_No, xferConfig); //send page address
|
||||
comm_out(0x10, xferConfig); //column address upper 4 bits + 0x10
|
||||
comm_out(0x00, xferConfig); //column address lower 4 bits + 0x00
|
||||
Page_No++;
|
||||
}
|
||||
|
||||
if(Number_of_Chars == MAX_CHARS_DISPLAYED) {
|
||||
Number_of_Chars++;
|
||||
}
|
||||
|
||||
if(ch == '\n') {
|
||||
comm_out(0xAF, xferConfig);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for(i = DisplayStart; i != (DisplayEnd+1); i++) {
|
||||
|
||||
if(Chars_Displayed_c == CHARS_PER_ROW) {
|
||||
Page_No++;
|
||||
|
||||
//Send the scrollbar
|
||||
if(needRefresh == 1){
|
||||
data_out(0xFF, xferConfig);
|
||||
data_out(0xFF, xferConfig);
|
||||
data_out(0xFF, xferConfig);
|
||||
}
|
||||
comm_out(Page_No, xferConfig); //send page address
|
||||
comm_out(0x10, xferConfig); //column address upper 4 bits + 0x10
|
||||
comm_out(0x00, xferConfig); //column address lower 4 bits + 0x00
|
||||
Chars_Displayed_c = 0;
|
||||
}
|
||||
|
||||
if(i == MAX_CHARS_DISPLAYED) {
|
||||
i = 0;
|
||||
}
|
||||
|
||||
//Calculate the indexes that are to be sent.
|
||||
ch = Chars_Displayed[i];
|
||||
for(Col = 0; Col < 7; Col++) {
|
||||
raw_value[Col] = x5x7_bits[(ch * 7) + Col];
|
||||
}
|
||||
|
||||
|
||||
raw = 0;
|
||||
raw = ((raw_value[0] & (0x8000)) >> 15) | ((raw_value[1] & (0x8000)) >> 14) | ((raw_value[2] & (0x8000)) >> 13)| ((raw_value[3] & (0x8000)) >> 12) | ((raw_value[4] & (0x8000)) >> 11) | ((raw_value[5] & (0x8000)) >> 10) | ((raw_value[6] & (0x8000)) >> 9);
|
||||
lcd_Values[0] = raw;
|
||||
|
||||
raw = 0;
|
||||
raw = ((raw_value[0] & (0x4000)) >> 14) | ((raw_value[1] & (0x4000)) >> 13) | ((raw_value[2] & (0x4000)) >> 12)| ((raw_value[3] & (0x4000)) >> 11) | ((raw_value[4] & (0x4000)) >> 10) | ((raw_value[5] & (0x4000)) >> 9) | ((raw_value[6] & (0x4000)) >> 8);
|
||||
lcd_Values[1] = raw;
|
||||
|
||||
raw = 0;
|
||||
raw = ((raw_value[0] & (0x2000)) >> 13) | ((raw_value[1] & (0x2000)) >> 12) | ((raw_value[2] & (0x2000)) >> 11)| ((raw_value[3] & (0x2000)) >> 10) | ((raw_value[4] & (0x2000)) >> 9) | ((raw_value[5] & (0x2000)) >> 8) | ((raw_value[6] & (0x2000)) >>7);
|
||||
lcd_Values[2] = raw;
|
||||
|
||||
raw = 0;
|
||||
raw = ((raw_value[0] & (0x1000)) >> 12) | ((raw_value[1] & (0x1000)) >> 11) | ((raw_value[2] & (0x1000)) >> 10)| ((raw_value[3] & (0x1000)) >> 9) | ((raw_value[4] & (0x1000)) >> 8) | ((raw_value[5] & (0x1000)) >> 7) | ((raw_value[6] & (0x1000)) >> 6);
|
||||
lcd_Values[3] = raw;
|
||||
|
||||
lcd_Values[4] = 0;
|
||||
|
||||
for(Col = 0; Col < FONT_WIDTH; Col++) {
|
||||
if(nHighlight || (Highlight_Value[i] == Highlight))
|
||||
data_out((~(lcd_Values[Col])) & 0x7F, xferConfig);
|
||||
else
|
||||
data_out(lcd_Values[Col], xferConfig);
|
||||
}
|
||||
|
||||
Chars_Displayed_c++;
|
||||
}
|
||||
//data_out(0, xferConfig);
|
||||
|
||||
if(needRefresh == 1) {
|
||||
//for(i = 0; i < CHARS_PER_ROW - 1; i++) {
|
||||
for(i = 0; i < CHARS_PER_ROW - 1; i++) {
|
||||
for(Col = 0; Col < FONT_WIDTH; Col++)
|
||||
data_out(0, xferConfig);
|
||||
}
|
||||
|
||||
//Send the scrollbar
|
||||
data_out(0xFF, xferConfig);
|
||||
data_out(0x81, xferConfig);
|
||||
data_out(0xFF, xferConfig);
|
||||
|
||||
comm_out(0x10, xferConfig); //column address upper 4 bits + 0x10
|
||||
comm_out(0x05, xferConfig); //column address lower 4 bits + 0x00
|
||||
}
|
||||
|
||||
comm_out(0xAF, xferConfig);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,329 @@
|
||||
/**********************************************************************
|
||||
* $Id$ debug_frmwrk.c 2011-06-02
|
||||
*//**
|
||||
* @file debug_frmwrk.c
|
||||
* @brief Contains some utilities that used for debugging through UART
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup DEBUG_FRMWRK
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _DEBUG_FRMWRK_
|
||||
#define _DEBUG_FRMWRK_
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "debug_frmwrk.h"
|
||||
#include "lpc43xx_scu.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#if defined(HITEX_LCD_TERM)
|
||||
#include "LCDTerm.h"
|
||||
#endif
|
||||
/* Debug framework */
|
||||
|
||||
void (*_db_msg)(LPC_USARTn_Type *UARTx, const void *s);
|
||||
void (*_db_msg_)(LPC_USARTn_Type *UARTx, const void *s);
|
||||
void (*_db_char)(LPC_USARTn_Type *UARTx, uint8_t ch);
|
||||
void (*_db_dec)(LPC_USARTn_Type *UARTx, uint8_t decn);
|
||||
void (*_db_dec_16)(LPC_USARTn_Type *UARTx, uint16_t decn);
|
||||
void (*_db_dec_32)(LPC_USARTn_Type *UARTx, uint32_t decn);
|
||||
void (*_db_hex)(LPC_USARTn_Type *UARTx, uint8_t hexn);
|
||||
void (*_db_hex_16)(LPC_USARTn_Type *UARTx, uint16_t hexn);
|
||||
void (*_db_hex_32)(LPC_USARTn_Type *UARTx, uint32_t hexn);
|
||||
uint8_t (*_db_get_char)(LPC_USARTn_Type *UARTx);
|
||||
|
||||
#if defined(HITEX_LCD_TERM)
|
||||
SSP_DATA_SETUP_Type *xferConfig;
|
||||
#endif
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Puts a character to UART port
|
||||
* @param[in] UARTx Pointer to UART peripheral
|
||||
* @param[in] ch Character to put
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void UARTPutChar (LPC_USARTn_Type *UARTx, uint8_t ch)
|
||||
{
|
||||
#if defined(HITEX_LCD_TERM)
|
||||
//Write character to the LCD
|
||||
WriteChar(ch, xferConfig, NoHighlight);
|
||||
#endif
|
||||
UART_Send(UARTx, &ch, 1, BLOCKING);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get a character to UART port
|
||||
* @param[in] UARTx Pointer to UART peripheral
|
||||
* @return character value that returned
|
||||
**********************************************************************/
|
||||
uint8_t UARTGetChar (LPC_USARTn_Type *UARTx)
|
||||
{
|
||||
uint8_t tmp = 0;
|
||||
UART_Receive(UARTx, &tmp, 1, BLOCKING);
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Puts a string to UART port
|
||||
* @param[in] UARTx Pointer to UART peripheral
|
||||
* @param[in] str string to put
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void UARTPuts(LPC_USARTn_Type *UARTx, const void *str)
|
||||
{
|
||||
uint8_t *s = (uint8_t *) str;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
UARTPutChar(UARTx, *s++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Puts a string to UART port and print new line
|
||||
* @param[in] UARTx Pointer to UART peripheral
|
||||
* @param[in] str String to put
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void UARTPuts_(LPC_USARTn_Type *UARTx, const void *str)
|
||||
{
|
||||
UARTPuts (UARTx, str);
|
||||
UARTPuts (UARTx, "\n\r");
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Puts a decimal number to UART port
|
||||
* @param[in] UARTx Pointer to UART peripheral
|
||||
* @param[in] decnum Decimal number (8-bit long)
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void UARTPutDec(LPC_USARTn_Type *UARTx, uint8_t decnum)
|
||||
{
|
||||
uint8_t c1=decnum%10;
|
||||
uint8_t c2=(decnum/10)%10;
|
||||
uint8_t c3=(decnum/100)%10;
|
||||
UARTPutChar(UARTx, '0'+c3);
|
||||
UARTPutChar(UARTx, '0'+c2);
|
||||
UARTPutChar(UARTx, '0'+c1);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Puts a decimal number to UART port
|
||||
* @param[in] UARTx Pointer to UART peripheral
|
||||
* @param[in] decnum Decimal number (8-bit long)
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void UARTPutDec16(LPC_USARTn_Type *UARTx, uint16_t decnum)
|
||||
{
|
||||
uint8_t c1=decnum%10;
|
||||
uint8_t c2=(decnum/10)%10;
|
||||
uint8_t c3=(decnum/100)%10;
|
||||
uint8_t c4=(decnum/1000)%10;
|
||||
uint8_t c5=(decnum/10000)%10;
|
||||
UARTPutChar(UARTx, '0'+c5);
|
||||
UARTPutChar(UARTx, '0'+c4);
|
||||
UARTPutChar(UARTx, '0'+c3);
|
||||
UARTPutChar(UARTx, '0'+c2);
|
||||
UARTPutChar(UARTx, '0'+c1);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Puts a decimal number to UART port
|
||||
* @param[in] UARTx Pointer to UART peripheral
|
||||
* @param[in] decnum Decimal number (8-bit long)
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void UARTPutDec32(LPC_USARTn_Type *UARTx, uint32_t decnum)
|
||||
{
|
||||
uint8_t c1=decnum%10;
|
||||
uint8_t c2=(decnum/10)%10;
|
||||
uint8_t c3=(decnum/100)%10;
|
||||
uint8_t c4=(decnum/1000)%10;
|
||||
uint8_t c5=(decnum/10000)%10;
|
||||
uint8_t c6=(decnum/100000)%10;
|
||||
uint8_t c7=(decnum/1000000)%10;
|
||||
uint8_t c8=(decnum/10000000)%10;
|
||||
uint8_t c9=(decnum/100000000)%10;
|
||||
uint8_t c10=(decnum/1000000000)%10;
|
||||
UARTPutChar(UARTx, '0'+c10);
|
||||
UARTPutChar(UARTx, '0'+c9);
|
||||
UARTPutChar(UARTx, '0'+c8);
|
||||
UARTPutChar(UARTx, '0'+c7);
|
||||
UARTPutChar(UARTx, '0'+c6);
|
||||
UARTPutChar(UARTx, '0'+c5);
|
||||
UARTPutChar(UARTx, '0'+c4);
|
||||
UARTPutChar(UARTx, '0'+c3);
|
||||
UARTPutChar(UARTx, '0'+c2);
|
||||
UARTPutChar(UARTx, '0'+c1);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Puts a hex number to UART port
|
||||
* @param[in] UARTx Pointer to UART peripheral
|
||||
* @param[in] hexnum Hex number (8-bit long)
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void UARTPutHex (LPC_USARTn_Type *UARTx, uint8_t hexnum)
|
||||
{
|
||||
uint8_t nibble, i;
|
||||
|
||||
UARTPuts(UARTx, "0x");
|
||||
i = 1;
|
||||
do {
|
||||
nibble = (hexnum >> (4*i)) & 0x0F;
|
||||
UARTPutChar(UARTx, (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble));
|
||||
} while (i--);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Puts a hex number to UART port
|
||||
* @param[in] UARTx Pointer to UART peripheral
|
||||
* @param[in] hexnum Hex number (16-bit long)
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void UARTPutHex16 (LPC_USARTn_Type *UARTx, uint16_t hexnum)
|
||||
{
|
||||
uint8_t nibble, i;
|
||||
|
||||
UARTPuts(UARTx, "0x");
|
||||
i = 3;
|
||||
do {
|
||||
nibble = (hexnum >> (4*i)) & 0x0F;
|
||||
UARTPutChar(UARTx, (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble));
|
||||
} while (i--);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Puts a hex number to UART port
|
||||
* @param[in] UARTx Pointer to UART peripheral
|
||||
* @param[in] hexnum Hex number (32-bit long)
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void UARTPutHex32 (LPC_USARTn_Type *UARTx, uint32_t hexnum)
|
||||
{
|
||||
uint8_t nibble, i;
|
||||
|
||||
UARTPuts(UARTx, "0x");
|
||||
i = 7;
|
||||
do {
|
||||
nibble = (hexnum >> (4*i)) & 0x0F;
|
||||
UARTPutChar(UARTx, (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble));
|
||||
} while (i--);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief print function that supports format as same as printf()
|
||||
* function of <stdio.h> library
|
||||
* @param[in] format formated string to be print
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void lpc_printf (const char *format, ...)
|
||||
{
|
||||
char buffer[512 + 1];
|
||||
va_list vArgs;
|
||||
va_start(vArgs, format);
|
||||
vsprintf((char *)buffer, (char const *)format, vArgs);
|
||||
va_end(vArgs);
|
||||
|
||||
_DBG(buffer);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Initialize Debug frame work through initializing UART port
|
||||
* @param[in] None
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void debug_frmwrk_init_clk(uint32_t Clock_Speed)
|
||||
{
|
||||
UART_CFG_Type UARTConfigStruct;
|
||||
|
||||
#if (USED_UART_DEBUG_PORT==0)
|
||||
/*
|
||||
* Initialize UART0 pin connect
|
||||
*/
|
||||
scu_pinmux(0xF ,10 , MD_PDN, FUNC1); // PF.10 : UART0_TXD
|
||||
scu_pinmux(0xF ,11 , MD_PLN|MD_EZI|MD_ZI, FUNC1); // PF.11 : UART0_RXD
|
||||
#elif (USED_UART_DEBUG_PORT==1)
|
||||
/*
|
||||
* Initialize UART1 pin connect
|
||||
*/
|
||||
scu_pinmux(0xC ,13 , MD_PDN, FUNC2); // PC.13 : UART1_TXD
|
||||
scu_pinmux(0xC ,14 , MD_PLN|MD_EZI|MD_ZI, FUNC2); // PC.14 : UART1_RXD
|
||||
#elif (USED_UART_DEBUG_PORT==3)
|
||||
/*
|
||||
* Initialize UART3 pin connect
|
||||
*/
|
||||
scu_pinmux(0x2 ,3 , MD_PUP, FUNC2); // P2.3 : UART3_TXD
|
||||
scu_pinmux(0x2 ,4 , MD_PLN|MD_EZI|MD_ZI, FUNC2); // P2.4 : UART3_RXD
|
||||
|
||||
#endif
|
||||
|
||||
/* Initialize UART Configuration parameter structure to default state:
|
||||
* Baudrate = 9600bps
|
||||
* 8 data bit
|
||||
* 1 Stop bit
|
||||
* None parity
|
||||
*/
|
||||
UART_ConfigStructInit(&UARTConfigStruct);
|
||||
// Re-configure baudrate to 115200bps
|
||||
UARTConfigStruct.Baud_rate = 115200;
|
||||
UARTConfigStruct.Clock_Speed = Clock_Speed;
|
||||
|
||||
// Initialize DEBUG_UART_PORT peripheral with given to corresponding parameter
|
||||
UART_Init((LPC_USARTn_Type*)DEBUG_UART_PORT, &UARTConfigStruct);
|
||||
|
||||
// Enable UART Transmit
|
||||
UART_TxCmd((LPC_USARTn_Type*)DEBUG_UART_PORT, ENABLE);
|
||||
|
||||
_db_msg = UARTPuts;
|
||||
_db_msg_ = UARTPuts_;
|
||||
_db_char = UARTPutChar;
|
||||
_db_hex = UARTPutHex;
|
||||
_db_hex_16 = UARTPutHex16;
|
||||
_db_hex_32 = UARTPutHex32;
|
||||
_db_dec = UARTPutDec;
|
||||
_db_dec_16 = UARTPutDec16;
|
||||
_db_dec_32 = UARTPutDec32;
|
||||
_db_get_char = UARTGetChar;
|
||||
#if defined(HITEX_LCD_TERM)
|
||||
xferConfig = InitLCDTerm();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* _DEBUG_FRMWRK_ */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,364 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_adc.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_adc.c
|
||||
* @brief Contains all functions support for ADC firmware library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup ADC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_adc.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
|
||||
#ifdef _ADC
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup ADC_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Initial for ADC
|
||||
* + Set bit PCADC
|
||||
* + Set clock for ADC
|
||||
* + Set Clock Frequency
|
||||
* @param[in] ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC
|
||||
* @param[in] rate ADC conversion rate, should be <=200KHz
|
||||
* @param[in] bits_accuracy number of bits accuracy, should be <=10 bits and >=3bits
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void ADC_Init(LPC_ADCn_Type *ADCx, uint32_t rate, uint8_t bits_accuracy)
|
||||
{
|
||||
uint32_t temp, tmpreg, ADCbitrate;
|
||||
|
||||
CHECK_PARAM(PARAM_ADCx(ADCx));
|
||||
CHECK_PARAM(PARAM_ADC_RATE(rate));
|
||||
|
||||
// Turn on power and clock
|
||||
//CGU_ConfigPPWR (CGU_PCONP_PCAD, ENABLE);
|
||||
|
||||
ADCx->CR = 0;
|
||||
|
||||
//Enable PDN bit
|
||||
tmpreg = ADC_CR_PDN;
|
||||
// Set clock frequency
|
||||
if(ADCx == LPC_ADC0)
|
||||
temp = CGU_GetPCLKFrequency(CGU_PERIPHERAL_ADC0);
|
||||
else if(ADCx == LPC_ADC1)
|
||||
temp = CGU_GetPCLKFrequency(CGU_PERIPHERAL_ADC1);
|
||||
/* The APB clock (PCLK_ADC0) is divided by (CLKDIV+1) to produce the clock for
|
||||
* A/D converter, which should be less than or equal to 13MHz.
|
||||
* A fully conversion requires (bits_accuracy+1) of these clocks.
|
||||
* ADC clock = PCLK_ADC0 / (CLKDIV + 1);
|
||||
* ADC rate = ADC clock / (bits_accuracy+1);
|
||||
*/
|
||||
ADCbitrate = (rate * (bits_accuracy+1));
|
||||
temp = ((temp*2 + ADCbitrate) / (ADCbitrate*2)) - 1;//get the round value by fomular: (2*A + B)/(2*B)
|
||||
tmpreg |= ADC_CR_CLKDIV(temp) | ADC_CR_BITACC(10 - bits_accuracy);
|
||||
|
||||
ADCx->CR = tmpreg;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Close ADC
|
||||
* @param[in] ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void ADC_DeInit(LPC_ADCn_Type *ADCx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ADCx(ADCx));
|
||||
|
||||
if (ADCx->CR & ADC_CR_START_MASK) //need to stop START bits before DeInit
|
||||
ADCx->CR &= ~ADC_CR_START_MASK;
|
||||
// Clear SEL bits
|
||||
ADCx->CR &= ~0xFF;
|
||||
// Clear PDN bit
|
||||
ADCx->CR &= ~ADC_CR_PDN;
|
||||
// Turn on power and clock
|
||||
//CGU_ConfigPPWR (CGU_PCONP_PCAD, DISABLE);
|
||||
}
|
||||
|
||||
|
||||
///*********************************************************************//**
|
||||
//* @brief Get Result conversion from A/D data register
|
||||
//* @param[in] channel number which want to read back the result
|
||||
//* @return Result of conversion
|
||||
//*********************************************************************/
|
||||
//uint32_t ADC_GetData(uint32_t channel)
|
||||
//{
|
||||
// uint32_t adc_value;
|
||||
//
|
||||
// CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));
|
||||
//
|
||||
// adc_value = *(uint32_t *)((&LPC_ADC->DR0) + channel);
|
||||
// return ADC_GDR_RESULT(adc_value);
|
||||
//}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set start mode for ADC
|
||||
* @param[in] ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC
|
||||
* @param[in] start_mode Start mode choose one of modes in
|
||||
* 'ADC_START_OPT' enumeration type definition, should be:
|
||||
* - ADC_START_CONTINUOUS
|
||||
* - ADC_START_NOW
|
||||
* - ADC_START_ON_EINT0
|
||||
* - ADC_START_ON_CAP01
|
||||
* - ADC_START_ON_MAT01
|
||||
* - ADC_START_ON_MAT03
|
||||
* - ADC_START_ON_MAT10
|
||||
* - ADC_START_ON_MAT11
|
||||
* @return None
|
||||
*********************************************************************/
|
||||
void ADC_StartCmd(LPC_ADCn_Type *ADCx, uint8_t start_mode)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ADCx(ADCx));
|
||||
CHECK_PARAM(PARAM_ADC_START_OPT(start_mode));
|
||||
|
||||
ADCx->CR &= ~ADC_CR_START_MASK;
|
||||
ADCx->CR |=ADC_CR_START_MODE_SEL((uint32_t)start_mode);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief ADC Burst mode setting
|
||||
* @param[in] ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC
|
||||
* @param[in] NewState
|
||||
* - 1: Set Burst mode
|
||||
* - 0: reset Burst mode
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void ADC_BurstCmd(LPC_ADCn_Type *ADCx, FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ADCx(ADCx));
|
||||
|
||||
ADCx->CR &= ~ADC_CR_BURST;
|
||||
if (NewState){
|
||||
ADCx->CR |= ADC_CR_BURST;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set AD conversion in power mode
|
||||
* @param[in] ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC
|
||||
* @param[in] NewState
|
||||
* - 1: AD converter is optional
|
||||
* - 0: AD Converter is in power down mode
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void ADC_PowerdownCmd(LPC_ADCn_Type *ADCx, FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ADCx(ADCx));
|
||||
|
||||
ADCx->CR &= ~ADC_CR_PDN;
|
||||
if (NewState){
|
||||
ADCx->CR |= ADC_CR_PDN;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set Edge start configuration
|
||||
* @param[in] ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC
|
||||
* @param[in] EdgeOption is ADC_START_ON_RISING and ADC_START_ON_FALLING
|
||||
* - 0: ADC_START_ON_RISING
|
||||
* - 1: ADC_START_ON_FALLING
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void ADC_EdgeStartConfig(LPC_ADCn_Type *ADCx, uint8_t EdgeOption)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ADCx(ADCx));
|
||||
CHECK_PARAM(PARAM_ADC_START_ON_EDGE_OPT(EdgeOption));
|
||||
|
||||
ADCx->CR &= ~ADC_CR_EDGE;
|
||||
if (EdgeOption){
|
||||
ADCx->CR |= ADC_CR_EDGE;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief ADC interrupt configuration
|
||||
* @param[in] ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC
|
||||
* @param[in] IntType: type of interrupt, should be:
|
||||
* - ADC_ADINTEN0: Interrupt channel 0
|
||||
* - ADC_ADINTEN1: Interrupt channel 1
|
||||
* ...
|
||||
* - ADC_ADINTEN7: Interrupt channel 7
|
||||
* - ADC_ADGINTEN: Individual channel/global flag done generate an interrupt
|
||||
* @param[in] NewState:
|
||||
* - SET : enable ADC interrupt
|
||||
* - RESET: disable ADC interrupt
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void ADC_IntConfig (LPC_ADCn_Type *ADCx, ADC_TYPE_INT_OPT IntType, FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ADCx(ADCx));
|
||||
CHECK_PARAM(PARAM_ADC_TYPE_INT_OPT(IntType));
|
||||
|
||||
ADCx->INTEN &= ~ADC_INTEN_CH(IntType);
|
||||
if (NewState){
|
||||
ADCx->INTEN |= ADC_INTEN_CH(IntType);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable/Disable ADC channel number
|
||||
* @param[in] ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC
|
||||
* @param[in] Channel channel number
|
||||
* @param[in] NewState New state, should be:
|
||||
* - ENABLE
|
||||
* - DISABLE
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void ADC_ChannelCmd (LPC_ADCn_Type *ADCx, uint8_t Channel, FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ADCx(ADCx));
|
||||
CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(Channel));
|
||||
|
||||
if (NewState == ENABLE) {
|
||||
ADCx->CR |= ADC_CR_CH_SEL(Channel);
|
||||
} else {
|
||||
if (ADCx->CR & ADC_CR_START_MASK) //need to stop START bits before disable channel
|
||||
ADCx->CR &= ~ADC_CR_START_MASK;
|
||||
ADCx->CR &= ~ADC_CR_CH_SEL(Channel);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get ADC result
|
||||
* @param[in] ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC
|
||||
* @param[in] channel channel number, should be 0...7
|
||||
* @return Converted data
|
||||
**********************************************************************/
|
||||
uint16_t ADC_ChannelGetData(LPC_ADCn_Type *ADCx, uint8_t channel)
|
||||
{
|
||||
uint32_t adc_value;
|
||||
|
||||
CHECK_PARAM(PARAM_ADCx(ADCx));
|
||||
CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));
|
||||
|
||||
adc_value = *(uint32_t *) ((&(ADCx->DR[0])) + channel);
|
||||
return ADC_DR_RESULT(adc_value);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get ADC Channel status from ADC data register
|
||||
* @param[in] ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC
|
||||
* @param[in] channel: channel number, should be 0..7
|
||||
* @param[in] StatusType
|
||||
* - 0: Burst status
|
||||
* - 1: Done status
|
||||
* @return Channel status, could be:
|
||||
* - SET
|
||||
* - RESET
|
||||
**********************************************************************/
|
||||
FlagStatus ADC_ChannelGetStatus(LPC_ADCn_Type *ADCx, uint8_t channel, uint32_t StatusType)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
CHECK_PARAM(PARAM_ADCx(ADCx));
|
||||
CHECK_PARAM(PARAM_ADC_CHANNEL_SELECTION(channel));
|
||||
CHECK_PARAM(PARAM_ADC_DATA_STATUS(StatusType));
|
||||
|
||||
temp = *(uint32_t *) ((&ADCx->DR[0]) + channel);
|
||||
if (StatusType) {
|
||||
temp &= ADC_DR_DONE_FLAG;
|
||||
}else{
|
||||
temp &= ADC_DR_OVERRUN_FLAG;
|
||||
}
|
||||
if (temp) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get ADC Data from AD Global register
|
||||
* @param[in] ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC
|
||||
* @return Result of conversion
|
||||
**********************************************************************/
|
||||
uint32_t ADC_GlobalGetData(LPC_ADCn_Type *ADCx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ADCx(ADCx));
|
||||
|
||||
return ((uint32_t)(ADCx->GDR));
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get ADC Chanel status from AD global data register
|
||||
* @param[in] ADCx pointer to LPC_ADCn_Type, should be: LPC_ADC
|
||||
* @param[in] StatusType
|
||||
* - 0: Burst status
|
||||
* - 1: Done status
|
||||
* @return SET / RESET
|
||||
**********************************************************************/
|
||||
FlagStatus ADC_GlobalGetStatus(LPC_ADCn_Type *ADCx, uint32_t StatusType)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
CHECK_PARAM(PARAM_ADCx(ADCx));
|
||||
CHECK_PARAM(PARAM_ADC_DATA_STATUS(StatusType));
|
||||
|
||||
temp = ADCx->GDR;
|
||||
if (StatusType){
|
||||
temp &= ADC_DR_DONE_FLAG;
|
||||
}else{
|
||||
temp &= ADC_DR_OVERRUN_FLAG;
|
||||
}
|
||||
if (temp){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _ADC */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* --------------------------------- End Of File ------------------------------ */
|
||||
@@ -0,0 +1,175 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_atimer.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_atimer.c
|
||||
* @brief Contains all functions support for Alarm Timer firmware
|
||||
* library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup ATIMER
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_atimer.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
#ifdef _ATIMER
|
||||
|
||||
/* Private Functions ---------------------------------------------------------- */
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Initial Alarm Timer device
|
||||
* @param[in] ATIMERx Timer selection, should be: LPC_ATIMER
|
||||
* @param[in] PresetValue Count of 1/1024s for Alarm
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void ATIMER_Init(LPC_ATIMER_Type *ATIMERx, uint32_t PresetValue)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ATIMERx(ATIMERx));
|
||||
|
||||
//set power
|
||||
if (ATIMERx== LPC_ATIMER)
|
||||
{
|
||||
/*Set Clock Here */
|
||||
CGU_EnableEntity(CGU_CLKSRC_32KHZ_OSC, ENABLE);
|
||||
}
|
||||
|
||||
ATIMER_UpdatePresetValue(ATIMERx, PresetValue);
|
||||
// Clear interrupt pending
|
||||
ATIMER_ClearIntStatus(ATIMERx);
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Close ATIMER device
|
||||
* @param[in] ATIMERx Pointer to timer device, should be: LPC_ATIMER
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void ATIMER_DeInit (LPC_ATIMER_Type *ATIMERx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ATIMERx(ATIMERx));
|
||||
// Disable atimer
|
||||
ATIMER_ClearIntStatus(ATIMERx);
|
||||
ATIMER_IntDisable(ATIMERx);
|
||||
|
||||
// Disable power
|
||||
// if (ATIMERx== LPC_ATIMER0)
|
||||
// CGU_ConfigPPWR (CGU_PCONP_PCATIMER0, DISABLE);
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Clear ATIMER Interrupt Status
|
||||
* @param[in] ATIMERx Pointer to timer device, should be: LPC_ATIMER
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void ATIMER_ClearIntStatus(LPC_ATIMER_Type *ATIMERx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ATIMERx(ATIMERx));
|
||||
ATIMERx->CLR_STAT = 1;
|
||||
while((ATIMERx->STATUS & 1) == 1);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set ATIMER Interrupt Status
|
||||
* @param[in] ATIMERx Pointer to timer device, should be: LPC_ATIMER
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void ATIMER_SetIntStatus(LPC_ATIMER_Type *ATIMERx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ATIMERx(ATIMERx));
|
||||
ATIMERx->SET_STAT = 1;
|
||||
while((ATIMERx->STATUS & 1) == 0);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable ATIMER Interrupt
|
||||
* @param[in] ATIMERx Pointer to timer device, should be: LPC_ATIMER
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void ATIMER_IntEnable(LPC_ATIMER_Type *ATIMERx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ATIMERx(ATIMERx));
|
||||
ATIMERx->SET_EN = 1;
|
||||
while((ATIMERx->ENABLE & 1) == 0);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Disable ATIMER Interrupt
|
||||
* @param[in] ATIMERx Pointer to timer device, should be: LPC_ATIMER
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void ATIMER_IntDisable(LPC_ATIMER_Type *ATIMERx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ATIMERx(ATIMERx));
|
||||
ATIMERx->CLR_EN = 1;
|
||||
while((ATIMERx->ENABLE & 1) == 1);
|
||||
}
|
||||
/*********************************************************************//**
|
||||
* @brief Update Preset value
|
||||
* @param[in] ATIMERx Pointer to timer device, should be: LPC_ATIMER
|
||||
* @param[in] PresetValue updated preset value
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void ATIMER_UpdatePresetValue(LPC_ATIMER_Type *ATIMERx,uint32_t PresetValue)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ATIMERx(ATIMERx));
|
||||
ATIMERx->PRESET = PresetValue;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Read value of preset register
|
||||
* @param[in] ATIMERx Pointer to timer/counter device, should be: LPC_ATIMER
|
||||
* @return Value of capture register
|
||||
**********************************************************************/
|
||||
uint32_t ATIMER_GetPresetValue(LPC_ATIMER_Type *ATIMERx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_ATIMERx(ATIMERx));
|
||||
return ATIMERx->PRESET;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _ATIMER */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,566 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_can.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_can.c
|
||||
* @brief Contains all functions support for C CAN firmware library
|
||||
* on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors�
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup C_CAN
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "LPC43xx.h"
|
||||
#include "lpc43xx_can.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
#ifdef _C_CAN
|
||||
|
||||
/* Private Macros ---------------------------------------------------------- */
|
||||
#ifndef __GNUC__
|
||||
/* Macro for reading and writing to CCAN IF registers */
|
||||
#define CAN_IF_Read(reg, IFsel) (LPC_C_CAN0->##IFsel##_##reg)
|
||||
#define CAN_IF_Write(reg, IFsel, val) (LPC_C_CAN0->##IFsel##_##reg=val)
|
||||
|
||||
/* Macro for writing IF to specific RAM message object */
|
||||
#define CAN_IF_readBuf(IFsel,msg) \
|
||||
LPC_C_CAN0->##IFsel##_##CMDMSK_W=RD|MASK|ARB|CTRL|CLRINTPND|DATAA|DATAB; \
|
||||
LPC_C_CAN0->##IFsel##_##CMDREQ=msg; \
|
||||
while (LPC_C_CAN0->##IFsel##_##CMDREQ & IFCREQ_BUSY );
|
||||
|
||||
/* Macro for reading specific RAM message object to IF */
|
||||
#define CAN_IF_writeBuf(IFsel,msg) \
|
||||
LPC_C_CAN0->##IFsel##_##CMDMSK_W=WR|MASK|ARB|CTRL|CLRINTPND|DATAA|DATAB; \
|
||||
LPC_C_CAN0->##IFsel##_##CMDREQ=msg; \
|
||||
while (LPC_C_CAN0->##IFsel##_##CMDREQ & IFCREQ_BUSY );
|
||||
#else
|
||||
#define CAN_IF_Read(reg, IFsel) (LPC_C_CAN0->IFsel##_##reg)
|
||||
#define CAN_IF_Write(reg, IFsel, val) (LPC_C_CAN0->IFsel ## _ ## reg = val)
|
||||
|
||||
/* Macro for writing IF to specific RAM message object */
|
||||
#define CAN_IF_readBuf(IFsel,msg) \
|
||||
LPC_C_CAN0->IFsel##_##CMDMSK_W=RD|MASK|ARB|CTRL|CLRINTPND|DATAA|DATAB; \
|
||||
LPC_C_CAN0->IFsel##_##CMDREQ=msg; \
|
||||
while (LPC_C_CAN0->IFsel##_##CMDREQ & IFCREQ_BUSY );
|
||||
|
||||
/* Macro for reading specific RAM message object to IF */
|
||||
#define CAN_IF_writeBuf(IFsel,msg) \
|
||||
LPC_C_CAN0->IFsel##_##CMDMSK_W=WR|MASK|ARB|CTRL|CLRINTPND|DATAA|DATAB; \
|
||||
LPC_C_CAN0->IFsel##_##CMDREQ=msg; \
|
||||
while (LPC_C_CAN0->IFsel##_##CMDREQ & IFCREQ_BUSY );
|
||||
#endif
|
||||
|
||||
#define IF1 0
|
||||
#define IF2 1
|
||||
|
||||
#define CAN_STATUS_INTERRUPT 0x8000 /* 0x0001-0x0020 are the # of the message
|
||||
object */
|
||||
/* 0x8000 is the status interrupt */
|
||||
|
||||
/* CAN Message interface register definitions */
|
||||
/* bit field of IF command request n register */
|
||||
#define IFCREQ_BUSY 0x8000 /* 1 is writing is progress, cleared when
|
||||
RD/WR done */
|
||||
/* CAN CTRL register */
|
||||
#define CTRL_INIT (1 << 0)
|
||||
#define CTRL_IE (1 << 1)
|
||||
#define CTRL_SIE (1 << 2)
|
||||
#define CTRL_EIE (1 << 3)
|
||||
#define CTRL_DAR (1 << 5)
|
||||
#define CTRL_CCE (1 << 6)
|
||||
#define CTRL_TEST (1 << 7)
|
||||
|
||||
/* CAN Test register */
|
||||
#define TEST_BASIC (1 << 2)
|
||||
#define TEST_SILENT (1 << 3)
|
||||
#define TEST_LBACK (1 << 4)
|
||||
|
||||
/* CAN Status register */
|
||||
#define STAT_LEC (0x7 << 0)
|
||||
#define STAT_TXOK (1 << 3)
|
||||
#define STAT_RXOK (1 << 4)
|
||||
#define STAT_EPASS (1 << 5)
|
||||
#define STAT_EWARN (1 << 6)
|
||||
#define STAT_BOFF (1 << 7)
|
||||
|
||||
#define NO_ERR 0 // No Error
|
||||
#define STUFF_ERR 1 // Stuff Error : More than 5 equal bits in a sequence have occurred in a part
|
||||
// of a received message where this is not allowed.
|
||||
#define FORM_ERR 2 // Form Error : A fixed format part of a received frame has the wrong format.
|
||||
#define ACK_ERR 3 // AckError : The message this CAN Core transmitted was not acknowledged
|
||||
// by another node.
|
||||
#define BIT1_ERR 4 // Bit1Error : During the transmission of a message (with the exception of
|
||||
// the arbitration field), the device wanted to send a recessive level (bit of
|
||||
// logical value �1�), but the monitored bus value was dominant.
|
||||
#define BIT0_ERR 5 // Bit0Error : During the transmission of a message (or acknowledge bit,
|
||||
// or active error flag, or overload flag), the device wanted to send a
|
||||
// LOW/dominant level (data or identifier bit logical value �0�), but the
|
||||
// monitored Bus value was HIGH/recessive. During busoff recovery this
|
||||
// status is set each time a
|
||||
// sequence of 11 HIGH/recessive bits has been monitored. This enables
|
||||
// the CPU to monitor the proceeding of the busoff recovery sequence
|
||||
// (indicating the bus is not stuck at LOW/dominant or continuously
|
||||
// disturbed).
|
||||
#define CRC_ERR 6 // CRCError: The CRC checksum was incorrect in the message received.
|
||||
|
||||
|
||||
/* bit field of IF command mask register */
|
||||
#define DATAB (1 << 0) /* 1 is transfer data byte 4-7 to message object, 0 is not */
|
||||
#define DATAA (1 << 1) /* 1 is transfer data byte 0-3 to message object, 0 is not */
|
||||
#define NEWDAT (1 << 2) /* Clear NEWDAT bit in the message object */
|
||||
#define CLRINTPND (1 << 3)
|
||||
#define CTRL (1 << 4) /* 1 is transfer the CTRL bit to the message object, 0 is not */
|
||||
#define ARB (1 << 5) /* 1 is transfer the ARB bits to the message object, 0 is not */
|
||||
#define MASK (1 << 6) /* 1 is transfer the MASK bit to the message object, 0 is not */
|
||||
#define WR (1 << 7) /* 0 is READ, 1 is WRITE */
|
||||
#define RD 0x0000
|
||||
|
||||
/* bit field of IF mask 2 register */
|
||||
#define MASK_MXTD (1 << 15) /* 1 extended identifier bit is used in the RX filter unit, 0 is not */
|
||||
#define MASK_MDIR (1 << 14) /* 1 direction bit is used in the RX filter unit, 0 is not */
|
||||
|
||||
/* bit field of IF identifier 2 register */
|
||||
#define ID_MVAL (1 << 15) /* Message valid bit, 1 is valid in the MO handler, 0 is ignored */
|
||||
#define ID_MTD (1 << 14) /* 1 extended identifier bit is used in the RX filter unit, 0 is not */
|
||||
#define ID_DIR (1 << 13) /* 1 direction bit is used in the RX filter unit, 0 is not */
|
||||
|
||||
/* bit field of IF message control register */
|
||||
#define NEWD (1 << 15) /* 1 indicates new data is in the message buffer. */
|
||||
#define MLST (1 << 14) /* 1 indicates a message loss. */
|
||||
#define INTP (1 << 13) /* 1 indicates message object is an interrupt source */
|
||||
#define UMSK (1 << 12) /* 1 is to use the mask for the receive filter mask. */
|
||||
#define TXIE (1 << 11) /* 1 is TX interrupt enabled */
|
||||
#define RXIE (1 << 10) /* 1 is RX interrupt enabled */
|
||||
|
||||
#if REMOTE_ENABLE
|
||||
#define RMTEN (1 << 9) /* 1 is remote frame enabled */
|
||||
#else
|
||||
#define RMTEN 0
|
||||
#endif
|
||||
|
||||
#define TXRQ (1 << 8) /* 1 is TxRqst enabled */
|
||||
#define EOB (1 << 7) /* End of buffer, always write to 1 */
|
||||
#define DLC 0x000F /* bit mask for DLC */
|
||||
|
||||
#define ID_STD_MASK 0x07FF
|
||||
#define ID_EXT_MASK 0x1FFFFFFF
|
||||
#define DLC_MASK 0x0F
|
||||
|
||||
/* Private Variables ---------------------------------------------------------- */
|
||||
/* Statistics of all the interrupts */
|
||||
/* Buss off status counter */
|
||||
volatile uint32_t BOffCnt = 0;
|
||||
/* Warning status counter. At least one of the error counters
|
||||
in the EML has reached the error warning limit of 96 */
|
||||
volatile uint32_t EWarnCnt = 0;
|
||||
/* More than 5 equal bits in a sequence in received message */
|
||||
volatile uint32_t StuffErrCnt = 0;
|
||||
/* Wrong format of fixed format part of a received frame */
|
||||
volatile uint32_t FormErrCnt = 0;
|
||||
/* Transmitted message not acknowledged. */
|
||||
volatile uint32_t AckErrCnt = 0;
|
||||
/* Send a HIGH/recessive level, but monitored LOW/dominant */
|
||||
volatile uint32_t Bit1ErrCnt = 0;
|
||||
/* Send a LOW/dominant level, but monitored HIGH/recessive */
|
||||
volatile uint32_t Bit0ErrCnt = 0;
|
||||
/* The CRC checksum was incorrect in the message received */
|
||||
volatile uint32_t CRCErrCnt = 0;
|
||||
/* Message object new data error counter */
|
||||
volatile uint32_t ND1ErrCnt = 0;
|
||||
|
||||
MSG_CB TX_cb, RX_cb;
|
||||
|
||||
message_object can_buff[CAN_MSG_OBJ_MAX];
|
||||
message_object recv_buff;
|
||||
|
||||
#if CAN_DEBUG
|
||||
uint32_t CANStatusLog[100];
|
||||
uint32_t CANStatusLogCount = 0;
|
||||
#endif
|
||||
|
||||
//#ifdef __GNUC__
|
||||
//uint32_t CAN_IF_Read(uint32_t reg,uint32_t IFsel){
|
||||
// if(IFsel == IF1){
|
||||
// return (LPC_C_CAN0->IF1_reg);
|
||||
// }else{
|
||||
// return (LPC_C_CAN0->IF2_reg);
|
||||
// }
|
||||
//}
|
||||
//void CAN_IF_Write(uint32_t reg, uint32_t IFsel,uint32_t val){
|
||||
// if(IFsel == IF1){
|
||||
// (LPC_C_CAN0->IF1_reg=val);
|
||||
// }else{
|
||||
// (LPC_C_CAN0->IF2_reg=val);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
///* Macro for writing IF to specific RAM message object */
|
||||
//void CAN_IF_readBuf(uint32_t IFsel,uint32_t msg){
|
||||
// if(IFsel == IF1){
|
||||
// LPC_C_CAN0->IF1_CMDMSK_W=RD|MASK|ARB|CTRL|CLRINTPND|DATAA|DATAB;
|
||||
// LPC_C_CAN0->IF1_CMDREQ=msg;
|
||||
// while (LPC_C_CAN0->IF1_CMDREQ & IFCREQ_BUSY );
|
||||
// }else{
|
||||
// LPC_C_CAN0->IF2_CMDMSK_W=RD|MASK|ARB|CTRL|CLRINTPND|DATAA|DATAB;
|
||||
// LPC_C_CAN0->IF2_CMDREQ=msg;
|
||||
// while (LPC_C_CAN0->IF2_CMDREQ & IFCREQ_BUSY );
|
||||
// }
|
||||
//
|
||||
//}
|
||||
//
|
||||
///* Macro for reading specific RAM message object to IF */
|
||||
//void CAN_IF_writeBuf(uint32_t IFsel,uint32_t msg){
|
||||
// if(IFsel == IF1){
|
||||
// LPC_C_CAN0->IF1_CMDMSK_W=WR|MASK|ARB|CTRL|CLRINTPND|DATAA|DATAB;
|
||||
// LPC_C_CAN0->IF1_CMDREQ=msg;
|
||||
// while (LPC_C_CAN0->IF1_CMDREQ & IFCREQ_BUSY );
|
||||
// }else{
|
||||
// LPC_C_CAN0->IF2_CMDMSK_W=WR|MASK|ARB|CTRL|CLRINTPND|DATAA|DATAB;
|
||||
// LPC_C_CAN0->IF2_CMDREQ=msg;
|
||||
// while (LPC_C_CAN0->IF2_CMDREQ & IFCREQ_BUSY );
|
||||
// }
|
||||
//}
|
||||
//#endif
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Handle valid received message
|
||||
* @param[in] msg_no Message Object number
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void CAN_RxInt_MessageProcess( uint8_t msg_no )
|
||||
{
|
||||
uint32_t msg_id;
|
||||
uint32_t *p_add;
|
||||
uint32_t reg1, reg2;
|
||||
|
||||
/* Import message object to IF2 */
|
||||
CAN_IF_readBuf(IF2, msg_no); /* Read the message into the IF registers */
|
||||
|
||||
p_add = (uint32_t *)&recv_buff;
|
||||
|
||||
if( CAN_IF_Read(ARB2, IF2) & ID_MTD ) /* bit 28-0 is 29 bit extended frame */
|
||||
{
|
||||
/* mask off MsgVal and Dir */
|
||||
reg1 = CAN_IF_Read(ARB1, IF2);
|
||||
reg2 = CAN_IF_Read(ARB2, IF2);
|
||||
msg_id = (reg1|(reg2<<16));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bit 28-18 is 11-bit standard frame */
|
||||
msg_id = (CAN_IF_Read(ARB2, IF2) &0x1FFF) >> 2;
|
||||
}
|
||||
|
||||
p_add[0] = msg_id;
|
||||
p_add[1] = CAN_IF_Read(MCTRL, IF2) & 0x000F; /* Get Msg Obj Data length */
|
||||
p_add[2] = (CAN_IF_Read(DA2, IF2)<<16) | CAN_IF_Read(DA1, IF2);
|
||||
p_add[3] = (CAN_IF_Read(DB2, IF2)<<16) | CAN_IF_Read(DB1, IF2);
|
||||
|
||||
/* Clear interrupt pending bit */
|
||||
CAN_IF_Write(MCTRL, IF2, UMSK|RXIE|EOB|CAN_DLC_MAX);
|
||||
/* Save changes to message RAM */
|
||||
CAN_IF_writeBuf(IF2, msg_no);
|
||||
|
||||
return;
|
||||
}
|
||||
/*********************************************************************//**
|
||||
* @brief Handle valid transmit message
|
||||
* @param[in] msg_no Message Object number
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void CAN_TxInt_MessageProcess( uint8_t msg_no )
|
||||
{
|
||||
/* Clear interrupt pending bit */
|
||||
CAN_IF_Write(MCTRL, IF2, UMSK|RXIE|EOB|CAN_DLC_MAX);
|
||||
/* Save changes to message RAM */
|
||||
CAN_IF_writeBuf(IF2,msg_no);
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief CAN interrupt handler
|
||||
* @param[in] None
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
volatile uint32_t nd_tmp;
|
||||
void CAN_IRQHandler(void)
|
||||
{
|
||||
uint32_t canstat = 0;
|
||||
uint32_t can_int, msg_no;
|
||||
|
||||
while ( (can_int = LPC_C_CAN0->INT) != 0 ) /* While interrupt is pending */
|
||||
{
|
||||
canstat = LPC_C_CAN0->STAT; /* Read CAN status register */
|
||||
|
||||
if ( can_int & CAN_STATUS_INTERRUPT )
|
||||
{
|
||||
/* Passive state monitored frequently in main. */
|
||||
|
||||
if ( canstat & STAT_EWARN )
|
||||
{
|
||||
EWarnCnt++;
|
||||
return;
|
||||
}
|
||||
if ( canstat & STAT_BOFF )
|
||||
{
|
||||
BOffCnt++;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (canstat&STAT_LEC) /* LEC Last Error Code (Type of the last error to occur on the CAN bus) */
|
||||
{
|
||||
case NO_ERR:
|
||||
break;
|
||||
case STUFF_ERR:
|
||||
StuffErrCnt++;
|
||||
break;
|
||||
case FORM_ERR:
|
||||
FormErrCnt++;
|
||||
break;
|
||||
case ACK_ERR:
|
||||
AckErrCnt++;
|
||||
break;
|
||||
case BIT1_ERR:
|
||||
Bit1ErrCnt++;
|
||||
break;
|
||||
case BIT0_ERR:
|
||||
Bit0ErrCnt++;
|
||||
break;
|
||||
case CRC_ERR:
|
||||
CRCErrCnt++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clear all warning/error states except RXOK/TXOK */
|
||||
LPC_C_CAN0->STAT &= STAT_RXOK|STAT_TXOK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (canstat & STAT_LEC) == 0 ) /* NO ERROR */
|
||||
{
|
||||
msg_no = can_int & 0x7FFF;
|
||||
if((msg_no >= 1 ) && (msg_no <= 16))
|
||||
{
|
||||
LPC_C_CAN0->STAT &= ~STAT_RXOK;
|
||||
/* Check if message number is correct by reading NEWDAT registers.
|
||||
By reading out the NEWDAT bits, the CPU can check for which Message
|
||||
Object the data portion was updated
|
||||
Only first 16 message object used for receive : only use ND1 */
|
||||
if((1<<(msg_no-1)) != LPC_C_CAN0->ND1)
|
||||
{
|
||||
/* message object does not contain new data! */
|
||||
ND1ErrCnt++;
|
||||
break;
|
||||
}
|
||||
CAN_RxInt_MessageProcess(msg_no);
|
||||
RX_cb(msg_no);
|
||||
}
|
||||
else
|
||||
{
|
||||
LPC_C_CAN0->STAT &= ~STAT_TXOK;
|
||||
CAN_TxInt_MessageProcess(msg_no);
|
||||
TX_cb(msg_no);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Initialize CAN peripheral
|
||||
* @param[in] BitClk CAN bit clock setting
|
||||
* @param[in] ClkDiv CAN bit clock setting
|
||||
* @param[in] Tx_cb point to call-back function when transmitted
|
||||
* @param[in] Rx_cb point to call-back function when received
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void CAN_Init( uint32_t BitClk, CCAN_CLKDIV_Type ClkDiv , MSG_CB Tx_cb, MSG_CB Rx_cb)
|
||||
{
|
||||
|
||||
RX_cb = Rx_cb;
|
||||
TX_cb = Tx_cb;
|
||||
if ( !(LPC_C_CAN0->CNTL & CTRL_INIT) )
|
||||
{
|
||||
/* If it's in normal operation already, stop it, reconfigure
|
||||
everything first, then restart. */
|
||||
LPC_C_CAN0->CNTL |= CTRL_INIT; /* Default state */
|
||||
}
|
||||
|
||||
LPC_C_CAN0->CLKDIV = ClkDiv; /* Divider for CAN VPB3 clock */
|
||||
LPC_C_CAN0->CNTL |= CTRL_CCE; /* Start configuring bit timing */
|
||||
LPC_C_CAN0->BT = BitClk;
|
||||
LPC_C_CAN0->BRPE = 0x0000;
|
||||
LPC_C_CAN0->CNTL &= ~CTRL_CCE; /* Stop configuring bit timing */
|
||||
|
||||
LPC_C_CAN0->CNTL &= ~CTRL_INIT; /* Initialization finished, normal operation now. */
|
||||
while ( LPC_C_CAN0->CNTL & CTRL_INIT );
|
||||
|
||||
/* By default, auto TX is enabled, enable all related interrupts */
|
||||
LPC_C_CAN0->CNTL |= (CTRL_IE|CTRL_SIE|CTRL_EIE);
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Send a message to the CAN port
|
||||
* @param[in] msg_no message object number
|
||||
* @param[in] msg_ptr msg buffer pointer
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void CAN_Send(uint8_t msg_no, uint32_t *msg_ptr )
|
||||
{
|
||||
uint32_t tx_id, Length;
|
||||
|
||||
if(msg_ptr == NULL) return;
|
||||
|
||||
/* first is the ID, second is length, the next four are data */
|
||||
tx_id = *msg_ptr++;
|
||||
Length = *msg_ptr++;
|
||||
|
||||
if(Length>CAN_DLC_MAX)Length = CAN_DLC_MAX;
|
||||
CAN_IF_Write(MCTRL, IF1, UMSK|TXIE|TXRQ|EOB|RMTEN|(Length & DLC_MASK));
|
||||
CAN_IF_Write(DA1, IF1, *msg_ptr); /* Lower two bytes of message pointer */
|
||||
CAN_IF_Write(DA2, IF1, (*msg_ptr++)>>16); /* Upper two bytes of message pointer */
|
||||
CAN_IF_Write(DB1, IF1, *msg_ptr); /* Lower two bytes of message pointer */
|
||||
CAN_IF_Write(DB2, IF1, (*msg_ptr)>>16); /* Upper two bytes of message pointer */
|
||||
|
||||
/* Configure arbitration */
|
||||
if(!(tx_id & (0x1<<30))) /* bit 30 is 0, standard frame */
|
||||
{
|
||||
/* Mxtd: 0, Mdir: 1, Mask is 0x7FF */
|
||||
CAN_IF_Write(MSK2, IF1, MASK_MDIR | (ID_STD_MASK << 2));
|
||||
CAN_IF_Write(MSK1, IF1, 0x0000);
|
||||
|
||||
/* MsgVal: 1, Mtd: 0, Dir: 1, ID = 0x200 */
|
||||
CAN_IF_Write(ARB1, IF1, 0x0000);
|
||||
CAN_IF_Write(ARB2, IF1, ID_MVAL| ID_DIR | (tx_id << 2));
|
||||
}
|
||||
else /* Extended frame */
|
||||
{
|
||||
/* Mxtd: 1, Mdir: 1, Mask is 0x7FF */
|
||||
CAN_IF_Write(MSK2, IF1, MASK_MXTD | MASK_MDIR | (ID_EXT_MASK >> 16));
|
||||
CAN_IF_Write(MSK1, IF1, ID_EXT_MASK & 0x0000FFFF);
|
||||
|
||||
/* MsgVal: 1, Mtd: 1, Dir: 1, ID = 0x200000 */
|
||||
CAN_IF_Write(ARB1, IF1, tx_id & 0x0000FFFF);
|
||||
CAN_IF_Write(ARB2, IF1, ID_MVAL|ID_MTD | ID_DIR | (tx_id >> 16));
|
||||
}
|
||||
|
||||
/* Write changes to message RAM */
|
||||
CAN_IF_writeBuf(IF1, msg_no);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Listen for a message on CAN bus
|
||||
* @param[in] msg_no message object number
|
||||
* @param[in] msg_ptr msg buffer pointer
|
||||
* @param[in] RemoteEnable Enable/disable remote frame support, should be:
|
||||
* - TRUE: enable
|
||||
* - FALSE: disable
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void CAN_Recv(uint8_t msg_no, uint32_t *msg_ptr, Bool RemoteEnable)
|
||||
{
|
||||
uint32_t rx_id = *msg_ptr;
|
||||
uint32_t rmten = 0;
|
||||
if(RemoteEnable){
|
||||
rmten = 1<<8;
|
||||
}
|
||||
if(!(rx_id & (0x1<<30))){ /* standard frame */
|
||||
|
||||
/* Mxtd: 0, Mdir: 0, Mask is 0x7FF */
|
||||
CAN_IF_Write(MSK1, IF1, 0x0000);
|
||||
CAN_IF_Write(MSK2, IF1, ID_STD_MASK << 2);
|
||||
/* MsgVal: 1, Mtd: 0, Dir: 0 */
|
||||
CAN_IF_Write(ARB1, IF1, 0x0000);
|
||||
CAN_IF_Write(MCTRL, IF1, rmten|UMSK|RXIE|EOB|CAN_DLC_MAX);
|
||||
CAN_IF_Write(DA1, IF1, 0x0000);
|
||||
CAN_IF_Write(DA2, IF1, 0x0000);
|
||||
CAN_IF_Write(DB1, IF1, 0x0000);
|
||||
CAN_IF_Write(DB2, IF1, 0x0000);
|
||||
CAN_IF_Write(ARB2, IF1, ID_MVAL | ((rx_id) << 2));
|
||||
/* Transfer data to message RAM */
|
||||
CAN_IF_writeBuf(IF1, msg_no);
|
||||
}
|
||||
|
||||
else{
|
||||
rx_id &= (0x1<<30)-1 ; /* Mask ID bit */
|
||||
/* Mxtd: 1, Mdir: 0, Mask is 0x1FFFFFFF */
|
||||
CAN_IF_Write(MSK1, IF1, ID_EXT_MASK & 0xFFFF);
|
||||
CAN_IF_Write(MSK2, IF1, MASK_MXTD | (ID_EXT_MASK >> 16));
|
||||
/* MsgVal: 1, Mtd: 1, Dir: 0 */
|
||||
CAN_IF_Write(ARB1, IF1, (rx_id) & 0xFFFF);
|
||||
CAN_IF_Write(MCTRL, IF1, rmten|UMSK|RXIE|EOB|CAN_DLC_MAX);
|
||||
CAN_IF_Write(DA1, IF1, 0x0000);
|
||||
CAN_IF_Write(DA2, IF1, 0x0000);
|
||||
CAN_IF_Write(DB1, IF1, 0x0000);
|
||||
CAN_IF_Write(DB2, IF1, 0x0000);
|
||||
CAN_IF_Write(ARB2, IF1, ID_MVAL | ID_MTD | ((rx_id) >> 16));
|
||||
/* Transfer data to message RAM */
|
||||
CAN_IF_writeBuf(IF1, msg_no);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Read a message from Message RAM to buffer
|
||||
* @param[in] msg_no message object number
|
||||
* @param[in] buff msg buffer pointer
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void CAN_ReadMsg(uint32_t msg_no, message_object* buff){
|
||||
int i;
|
||||
buff->id = recv_buff.id;
|
||||
buff->dlc = recv_buff.dlc;
|
||||
if(recv_buff.dlc>CAN_DLC_MAX) recv_buff.dlc = CAN_DLC_MAX;
|
||||
for(i=0;i<recv_buff.dlc;i++)
|
||||
buff->data[i] = recv_buff.data[i];
|
||||
}
|
||||
|
||||
#endif /* _C_CAN*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* --------------------------------- End Of File ------------------------------ */
|
||||
|
||||
@@ -0,0 +1,970 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_cgu.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_cgu.c
|
||||
* @brief Contains all functions support for Clock Generation and Control
|
||||
* firmware library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors�
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup CGU
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc_types.h"
|
||||
#include "lpc43xx_scu.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
|
||||
/** This define used to fix mistake when run with IAR compiler */
|
||||
#ifdef __ICCARM__
|
||||
#define CGU_BRANCH_STATUS_ENABLE_MASK 0x80000001
|
||||
#else
|
||||
#define CGU_BRANCH_STATUS_ENABLE_MASK 0x01
|
||||
#endif
|
||||
|
||||
/*TODO List:
|
||||
* SET PLL0
|
||||
* UPDATE Clock from PLL0
|
||||
* SetDIV uncheck value
|
||||
* GetBaseStatus BASE_SAFE
|
||||
* */
|
||||
/* Local definition */
|
||||
#define CGU_ADDRESS32(x,y) (*(uint32_t*)((uint32_t)x+y))
|
||||
|
||||
/* Local Variable */
|
||||
const int16_t CGU_Entity_ControlReg_Offset[CGU_ENTITY_NUM] = {
|
||||
-1, //CGU_CLKSRC_32KHZ_OSC,
|
||||
-1, //CGU_CLKSRC_IRC,
|
||||
-1, //CGU_CLKSRC_ENET_RX_CLK,
|
||||
-1, //CGU_CLKSRC_ENET_TX_CLK,
|
||||
-1, //CGU_CLKSRC_GP_CLKIN,
|
||||
-1, //CGU_CLKSRC_TCK,
|
||||
0x18, //CGU_CLKSRC_XTAL_OSC,
|
||||
0x20, //CGU_CLKSRC_PLL0,
|
||||
0x30, //CGU_CLKSRC_PLL0_AUDIO **REV A**
|
||||
0x44, //CGU_CLKSRC_PLL1,
|
||||
-1, //CGU_CLKSRC_RESERVE,
|
||||
-1, //CGU_CLKSRC_RESERVE,
|
||||
0x48, //CGU_CLKSRC_IDIVA,,
|
||||
0x4C, //CGU_CLKSRC_IDIVB,
|
||||
0x50, //CGU_CLKSRC_IDIVC,
|
||||
0x54, //CGU_CLKSRC_IDIVD,
|
||||
0x58, //CGU_CLKSRC_IDIVE,
|
||||
|
||||
0x5C, //CGU_BASE_SAFE,
|
||||
0x60, //CGU_BASE_USB0,
|
||||
0x64, //CGU_BASE_PERIPH, // used for SPGPIO, peripheral control
|
||||
0x68, //CGU_BASE_USB1,
|
||||
0x6C, //CGU_BASE_M4,
|
||||
0x70, //CGU_BASE_SPIFI,
|
||||
-1, //CGU_BASE_RESERVE,
|
||||
0x78, //CGU_BASE_PHY_RX,
|
||||
0x7C, //CGU_BASE_PHY_TX,
|
||||
0x80, //CGU_BASE_APB1,
|
||||
0x84, //CGU_BASE_APB3,
|
||||
0x88, //CGU_BASE_LCD,
|
||||
0X8C, //CGU_BASE_ENET_CSR, **REV A**
|
||||
0x90, //CGU_BASE_SDIO,
|
||||
0x94, //CGU_BASE_SSP0,
|
||||
0x98, //CGU_BASE_SSP1,
|
||||
0x9C, //CGU_BASE_UART0,
|
||||
0xA0, //CGU_BASE_UART1,
|
||||
0xA4, //CGU_BASE_UART2,
|
||||
0xA8, //CGU_BASE_UART3,
|
||||
0xAC, //CGU_BASE_CLKOUT
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
0xC0, //CGU_BASE_APLL
|
||||
0xC4, //CGU_BASE_OUT0
|
||||
0xC8 //CGU_BASE_OUT1
|
||||
};
|
||||
|
||||
const uint8_t CGU_ConnectAlloc_Tbl[CGU_CLKSRC_NUM][CGU_ENTITY_NUM] = {
|
||||
// 3 I E E G T X P P P x x D D D D D S U P U M S x P P A A L E S S S U U U U C x x x x A O O
|
||||
// 2 R R T P C T L L L I I I I I A S E S 3 P H H P P C N D S S R R R R O P U U
|
||||
// C X X I K A 0 A 1 A B C D E F B R B F RxTx1 3 D T I 0 1 0 1 2 3 L T T
|
||||
{0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_32KHZ_OSC = 0,*/
|
||||
{0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_IRC,*/
|
||||
{0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_ENET_RX_CLK,*/
|
||||
{0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_ENET_TX_CLK,*/
|
||||
{0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_GP_CLKIN,*/
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0},/*CGU_CLKSRC_TCK,*/
|
||||
{0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_XTAL_OSC,*/
|
||||
{0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1},/*CGU_CLKSRC_PLL0,*/
|
||||
{0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_PLL0_AUDIO,*/
|
||||
{0,0,0,0,0,0,0,1,1,0,0,0,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_PLL1,*/
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_IDIVA = CGU_CLKSRC_PLL1 + 3,*/
|
||||
{0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_IDIVB,*/
|
||||
{0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_IDIVC,*/
|
||||
{0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1},/*CGU_CLKSRC_IDIVD,*/
|
||||
{0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1}/*CGU_CLKSRC_IDIVE,*/
|
||||
};
|
||||
|
||||
const CGU_PERIPHERAL_S CGU_PERIPHERAL_Info[CGU_PERIPHERAL_NUM] = {
|
||||
/* Register Clock | Peripheral Clock
|
||||
| BASE | BRANCH | BASE | BRANCH */
|
||||
{CGU_BASE_APB3, 0x1118, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_ADC0,
|
||||
{CGU_BASE_APB3, 0x1120, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_ADC1,
|
||||
{CGU_BASE_M4, 0x1460, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_AES,
|
||||
//// CGU_PERIPHERAL_ALARMTIMER_CGU_RGU_RTC_WIC,
|
||||
{CGU_BASE_APB1, 0x1200, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_APB1_BUS,
|
||||
{CGU_BASE_APB3, 0x1100, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_APB3_BUS,
|
||||
{CGU_BASE_APB3, 0x1128, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_CAN0,
|
||||
{CGU_BASE_M4, 0x1538, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_CREG,
|
||||
{CGU_BASE_APB3, 0x1110, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_DAC,
|
||||
{CGU_BASE_M4, 0x1440, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_DMA,
|
||||
{CGU_BASE_M4, 0x1430, CGU_BASE_M4, 0x1478, 0},//CGU_PERIPHERAL_EMC,
|
||||
{CGU_BASE_M4, 0x1420, CGU_BASE_PHY_RX, 0x0000, CGU_PERIPHERAL_ETHERNET_TX},//CGU_PERIPHERAL_ETHERNET,
|
||||
{CGU_ENTITY_NONE,0x0000, CGU_BASE_PHY_TX, 0x0000, 0},//CGU_PERIPHERAL_ETHERNET_TX
|
||||
{CGU_BASE_M4, 0x1410, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_GPIO,
|
||||
{CGU_BASE_APB1, 0x1210, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_I2C0,
|
||||
{CGU_BASE_APB3, 0x1108, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_I2C1,
|
||||
{CGU_BASE_APB1, 0x1218, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_I2S,
|
||||
{CGU_BASE_M4, 0x1418, CGU_BASE_LCD, 0x0000, 0},//CGU_PERIPHERAL_LCD,
|
||||
{CGU_BASE_M4, 0x1448, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_M3CORE,
|
||||
{CGU_BASE_M4, 0x1400, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_M3_BUS,
|
||||
{CGU_BASE_APB1, 0x1208, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_MOTOCON,
|
||||
{CGU_BASE_M4, 0x1630, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_QEI,
|
||||
{CGU_BASE_M4, 0x1600, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_RITIMER,
|
||||
{CGU_BASE_M4, 0x1468, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_SCT,
|
||||
{CGU_BASE_M4, 0x1530, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_SCU,
|
||||
{CGU_BASE_M4, 0x1438, CGU_BASE_SDIO, 0x2800, 0},//CGU_PERIPHERAL_SDIO,
|
||||
{CGU_BASE_M4, 0x1408, CGU_BASE_SPIFI, 0x1300, 0},//CGU_PERIPHERAL_SPIFI,
|
||||
{CGU_BASE_M4, 0x1518, CGU_BASE_SSP0, 0x2700, 0},//CGU_PERIPHERAL_SSP0,
|
||||
{CGU_BASE_M4, 0x1628, CGU_BASE_SSP1, 0x2600, 0},//CGU_PERIPHERAL_SSP1,
|
||||
{CGU_BASE_M4, 0x1520, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_TIMER0,
|
||||
{CGU_BASE_M4, 0x1528, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_TIMER1,
|
||||
{CGU_BASE_M4, 0x1618, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_TIMER2,
|
||||
{CGU_BASE_M4, 0x1620, CGU_ENTITY_NONE, 0x0000, 0},//CGU_PERIPHERAL_TIMER3,
|
||||
{CGU_BASE_M4, 0x1508, CGU_BASE_UART0, 0x2500, 0},//CGU_PERIPHERAL_UART0,
|
||||
{CGU_BASE_M4, 0x1510, CGU_BASE_UART1, 0x2400, 0},//CGU_PERIPHERAL_UART1,
|
||||
{CGU_BASE_M4, 0x1608, CGU_BASE_UART2, 0x2300, 0},//CGU_PERIPHERAL_UART2,
|
||||
{CGU_BASE_M4, 0x1610, CGU_BASE_UART3, 0x2200, 0},//CGU_PERIPHERAL_UART3,
|
||||
{CGU_BASE_M4, 0x1428, CGU_BASE_USB0, 0x1800, 0},//CGU_PERIPHERAL_USB0,
|
||||
{CGU_BASE_M4, 0x1470, CGU_BASE_USB1, 0x1900, 0},//CGU_PERIPHERAL_USB1,
|
||||
{CGU_BASE_M4, 0x1500, CGU_BASE_SAFE, 0x0000, 0},//CGU_PERIPHERAL_WWDT,
|
||||
};
|
||||
|
||||
uint32_t CGU_ClockSourceFrequency[CGU_CLKSRC_NUM] = {0,12000000,0,0,0,0, 0, 480000000,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
#define CGU_CGU_ADDR ((uint32_t)LPC_CGU)
|
||||
#define CGU_REG_BASE_CTRL(x) (*(uint32_t*)(CGU_CGU_ADDR+CGU_Entity_ControlReg_Offset[CGU_PERIPHERAL_Info[x].RegBaseEntity]))
|
||||
#define CGU_REG_BRANCH_CTRL(x) (*(uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].RegBranchOffset))
|
||||
#define CGU_REG_BRANCH_STATUS(x) (*(volatile uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].RegBranchOffset+4))
|
||||
|
||||
#define CGU_PER_BASE_CTRL(x) (*(uint32_t*)(CGU_CGU_ADDR+CGU_Entity_ControlReg_Offset[CGU_PERIPHERAL_Info[x].PerBaseEntity]))
|
||||
#define CGU_PER_BRANCH_CTRL(x) (*(uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].PerBranchOffset))
|
||||
#define CGU_PER_BRANCH_STATUS(x) (*(volatile uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].PerBranchOffset+4))
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Initialize default clock for LPC4300 Eval board
|
||||
* @param[in] None
|
||||
* @return Initialize status, could be:
|
||||
* - CGU_ERROR_SUCCESS: successful
|
||||
* - Other: error
|
||||
**********************************************************************/
|
||||
uint32_t CGU_Init(void){
|
||||
CGU_SetXTALOSC(12000000);
|
||||
CGU_EnableEntity(CGU_CLKSRC_XTAL_OSC, ENABLE);
|
||||
CGU_EntityConnect(CGU_CLKSRC_XTAL_OSC, CGU_CLKSRC_PLL1);
|
||||
// Disable PLL1 CPU hang???
|
||||
//CGU_EnableEntity(CGU_CLKSRC_PLL1, DISABLE);
|
||||
CGU_SetPLL1(6);
|
||||
// CGU_SetPLL1(5);
|
||||
CGU_EnableEntity(CGU_CLKSRC_PLL1, ENABLE);
|
||||
CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_M4);
|
||||
CGU_UpdateClock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Configure power for individual peripheral
|
||||
* @param[in] PPType peripheral type, should be:
|
||||
* - CGU_PERIPHERAL_ADC0 :ADC0
|
||||
* - CGU_PERIPHERAL_ADC1 :ADC1
|
||||
* - CGU_PERIPHERAL_AES :AES
|
||||
* - CGU_PERIPHERAL_APB1_BUS :APB1 bus
|
||||
* - CGU_PERIPHERAL_APB3_BUS :APB3 bus
|
||||
* - CGU_PERIPHERAL_CAN :CAN
|
||||
* - CGU_PERIPHERAL_CREG :CREG
|
||||
* - CGU_PERIPHERAL_DAC :DAC
|
||||
* - CGU_PERIPHERAL_DMA :DMA
|
||||
* - CGU_PERIPHERAL_EMC :EMC
|
||||
* - CGU_PERIPHERAL_ETHERNET :ETHERNET
|
||||
* - CGU_PERIPHERAL_GPIO :GPIO
|
||||
* - CGU_PERIPHERAL_I2C0 :I2C0
|
||||
* - CGU_PERIPHERAL_I2C1 :I2C1
|
||||
* - CGU_PERIPHERAL_I2S :I2S
|
||||
* - CGU_PERIPHERAL_LCD :LCD
|
||||
* - CGU_PERIPHERAL_M3CORE :M3 core
|
||||
* - CGU_PERIPHERAL_M3_BUS :M3 bus
|
||||
* - CGU_PERIPHERAL_MOTOCON :Motor control
|
||||
* - CGU_PERIPHERAL_QEI :QEI
|
||||
* - CGU_PERIPHERAL_RITIMER :RIT timer
|
||||
* - CGU_PERIPHERAL_SCT :SCT
|
||||
* - CGU_PERIPHERAL_SCU :SCU
|
||||
* - CGU_PERIPHERAL_SDIO :SDIO
|
||||
* - CGU_PERIPHERAL_SPIFI :SPIFI
|
||||
* - CGU_PERIPHERAL_SSP0 :SSP0
|
||||
* - CGU_PERIPHERAL_SSP1 :SSP1
|
||||
* - CGU_PERIPHERAL_TIMER0 :TIMER0
|
||||
* - CGU_PERIPHERAL_TIMER1 :TIMER1
|
||||
* - CGU_PERIPHERAL_TIMER2 :TIMER2
|
||||
* - CGU_PERIPHERAL_TIMER3 :TIMER3
|
||||
* - CGU_PERIPHERAL_UART0 :UART0
|
||||
* - CGU_PERIPHERAL_UART1 :UART1
|
||||
* - CGU_PERIPHERAL_UART2 :UART2
|
||||
* - CGU_PERIPHERAL_UART3 :UART3
|
||||
* - CGU_PERIPHERAL_USB0 :USB0
|
||||
* - CGU_PERIPHERAL_USB1 :USB1
|
||||
* - CGU_PERIPHERAL_WWDT :WWDT
|
||||
* @param[in] en status, should be:
|
||||
* - ENABLE: Enable power
|
||||
* - DISABLE: Disable power
|
||||
* @return Configure status, could be:
|
||||
* - CGU_ERROR_SUCCESS: successful
|
||||
* - Other: error
|
||||
**********************************************************************/
|
||||
uint32_t CGU_ConfigPWR (CGU_PERIPHERAL_T PPType, FunctionalState en){
|
||||
if(PPType >= CGU_PERIPHERAL_WWDT && PPType <= CGU_PERIPHERAL_ADC0)
|
||||
return CGU_ERROR_INVALID_PARAM;
|
||||
if(en == DISABLE){/* Going to disable clock */
|
||||
/*Get Reg branch status */
|
||||
if(CGU_PERIPHERAL_Info[PPType].RegBranchOffset!= 0 &&
|
||||
CGU_REG_BRANCH_STATUS(PPType) & 1){
|
||||
CGU_REG_BRANCH_CTRL(PPType) &= ~1; /* Disable branch clock */
|
||||
while(CGU_REG_BRANCH_STATUS(PPType) & 1);
|
||||
}
|
||||
/* GetBase Status*/
|
||||
if((CGU_PERIPHERAL_Info[PPType].RegBaseEntity!=CGU_ENTITY_NONE) &&
|
||||
CGU_GetBaseStatus((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].RegBaseEntity) == 0){
|
||||
/* Disable Base */
|
||||
CGU_EnableEntity((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].RegBaseEntity,0);
|
||||
}
|
||||
|
||||
/* Same for Peripheral */
|
||||
if((CGU_PERIPHERAL_Info[PPType].PerBranchOffset!= 0) && (CGU_PER_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK)){
|
||||
CGU_PER_BRANCH_CTRL(PPType) &= ~1; /* Disable branch clock */
|
||||
while(CGU_PER_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK);
|
||||
}
|
||||
/* GetBase Status*/
|
||||
if((CGU_PERIPHERAL_Info[PPType].PerBaseEntity!=CGU_ENTITY_NONE) &&
|
||||
CGU_GetBaseStatus((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].PerBaseEntity) == 0){
|
||||
/* Disable Base */
|
||||
CGU_EnableEntity((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].PerBaseEntity,0);
|
||||
}
|
||||
}else{
|
||||
/* enable */
|
||||
/* GetBase Status*/
|
||||
if((CGU_PERIPHERAL_Info[PPType].RegBaseEntity!=CGU_ENTITY_NONE) && CGU_REG_BASE_CTRL(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK){
|
||||
/* Enable Base */
|
||||
CGU_EnableEntity((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].RegBaseEntity, 1);
|
||||
}
|
||||
/*Get Reg branch status */
|
||||
if((CGU_PERIPHERAL_Info[PPType].RegBranchOffset!= 0) && !(CGU_REG_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK)){
|
||||
CGU_REG_BRANCH_CTRL(PPType) |= 1; /* Enable branch clock */
|
||||
while(!(CGU_REG_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK));
|
||||
}
|
||||
|
||||
/* Same for Peripheral */
|
||||
/* GetBase Status*/
|
||||
if((CGU_PERIPHERAL_Info[PPType].PerBaseEntity != CGU_ENTITY_NONE) &&
|
||||
(CGU_PER_BASE_CTRL(PPType) & 1)){
|
||||
/* Enable Base */
|
||||
CGU_EnableEntity((CGU_ENTITY_T)CGU_PERIPHERAL_Info[PPType].PerBaseEntity, 1);
|
||||
}
|
||||
/*Get Reg branch status */
|
||||
if((CGU_PERIPHERAL_Info[PPType].PerBranchOffset!= 0) && !(CGU_PER_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK)){
|
||||
CGU_PER_BRANCH_CTRL(PPType) |= 1; /* Enable branch clock */
|
||||
while(!(CGU_PER_BRANCH_STATUS(PPType) & CGU_BRANCH_STATUS_ENABLE_MASK));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(CGU_PERIPHERAL_Info[PPType].next){
|
||||
return CGU_ConfigPWR((CGU_PERIPHERAL_T)CGU_PERIPHERAL_Info[PPType].next, en);
|
||||
}
|
||||
return CGU_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get peripheral clock frequency
|
||||
* @param[in] Clock Peripheral type, should be:
|
||||
* - CGU_PERIPHERAL_ADC0 :ADC0
|
||||
* - CGU_PERIPHERAL_ADC1 :ADC1
|
||||
* - CGU_PERIPHERAL_AES :AES
|
||||
* - CGU_PERIPHERAL_APB1_BUS :APB1 bus
|
||||
* - CGU_PERIPHERAL_APB3_BUS :APB3 bus
|
||||
* - CGU_PERIPHERAL_CAN :CAN
|
||||
* - CGU_PERIPHERAL_CREG :CREG
|
||||
* - CGU_PERIPHERAL_DAC :DAC
|
||||
* - CGU_PERIPHERAL_DMA :DMA
|
||||
* - CGU_PERIPHERAL_EMC :EMC
|
||||
* - CGU_PERIPHERAL_ETHERNET :ETHERNET
|
||||
* - CGU_PERIPHERAL_GPIO :GPIO
|
||||
* - CGU_PERIPHERAL_I2C0 :I2C0
|
||||
* - CGU_PERIPHERAL_I2C1 :I2C1
|
||||
* - CGU_PERIPHERAL_I2S :I2S
|
||||
* - CGU_PERIPHERAL_LCD :LCD
|
||||
* - CGU_PERIPHERAL_M3CORE :M3 core
|
||||
* - CGU_PERIPHERAL_M3_BUS :M3 bus
|
||||
* - CGU_PERIPHERAL_MOTOCON :Motor control
|
||||
* - CGU_PERIPHERAL_QEI :QEI
|
||||
* - CGU_PERIPHERAL_RITIMER :RIT timer
|
||||
* - CGU_PERIPHERAL_SCT :SCT
|
||||
* - CGU_PERIPHERAL_SCU :SCU
|
||||
* - CGU_PERIPHERAL_SDIO :SDIO
|
||||
* - CGU_PERIPHERAL_SPIFI :SPIFI
|
||||
* - CGU_PERIPHERAL_SSP0 :SSP0
|
||||
* - CGU_PERIPHERAL_SSP1 :SSP1
|
||||
* - CGU_PERIPHERAL_TIMER0 :TIMER0
|
||||
* - CGU_PERIPHERAL_TIMER1 :TIMER1
|
||||
* - CGU_PERIPHERAL_TIMER2 :TIMER2
|
||||
* - CGU_PERIPHERAL_TIMER3 :TIMER3
|
||||
* - CGU_PERIPHERAL_UART0 :UART0
|
||||
* - CGU_PERIPHERAL_UART1 :UART1
|
||||
* - CGU_PERIPHERAL_UART2 :UART2
|
||||
* - CGU_PERIPHERAL_UART3 :UART3
|
||||
* - CGU_PERIPHERAL_USB0 :USB0
|
||||
* - CGU_PERIPHERAL_USB1 :USB1
|
||||
* - CGU_PERIPHERAL_WWDT :WWDT
|
||||
* @return Return frequently value
|
||||
**********************************************************************/
|
||||
uint32_t CGU_GetPCLKFrequency (CGU_PERIPHERAL_T Clock){
|
||||
uint32_t ClkSrc;
|
||||
if(Clock >= CGU_PERIPHERAL_WWDT && Clock <= CGU_PERIPHERAL_ADC0)
|
||||
return CGU_ERROR_INVALID_PARAM;
|
||||
|
||||
if(CGU_PERIPHERAL_Info[Clock].PerBaseEntity != CGU_ENTITY_NONE){
|
||||
/* Get Base Clock Source */
|
||||
ClkSrc = (CGU_PER_BASE_CTRL(Clock) & CGU_CTRL_SRC_MASK) >> 24;
|
||||
/* GetBase Status*/
|
||||
if(CGU_PER_BASE_CTRL(Clock) & 1)
|
||||
return 0;
|
||||
/* check Branch if it is enabled */
|
||||
if((CGU_PERIPHERAL_Info[Clock].PerBranchOffset!= 0) && !(CGU_PER_BRANCH_STATUS(Clock) & CGU_BRANCH_STATUS_ENABLE_MASK)) return 0;
|
||||
}else{
|
||||
if(CGU_REG_BASE_CTRL(Clock) & 1) return 0;
|
||||
ClkSrc = (CGU_REG_BASE_CTRL(Clock) & CGU_CTRL_SRC_MASK) >> 24;
|
||||
/* check Branch if it is enabled */
|
||||
if((CGU_PERIPHERAL_Info[Clock].RegBranchOffset!= 0) && !(CGU_REG_BRANCH_STATUS(Clock) & CGU_BRANCH_STATUS_ENABLE_MASK)) return 0;
|
||||
}
|
||||
return CGU_ClockSourceFrequency[ClkSrc];
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Update clock
|
||||
* @param[in] None
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void CGU_UpdateClock(void){
|
||||
uint32_t ClkSrc;
|
||||
uint32_t div;
|
||||
uint32_t divisor;
|
||||
int32_t RegOffset;
|
||||
/* 32OSC */
|
||||
if(ISBITSET(LPC_CREG->CREG0,1) && ISBITCLR(LPC_CREG->CREG0,3))
|
||||
CGU_ClockSourceFrequency[CGU_CLKSRC_32KHZ_OSC] = 32768;
|
||||
else
|
||||
CGU_ClockSourceFrequency[CGU_CLKSRC_32KHZ_OSC] = 0;
|
||||
/*PLL0*/
|
||||
/* PLL1 */
|
||||
if(ISBITCLR(LPC_CGU->PLL1_CTRL,1) /* Enabled */
|
||||
&& (LPC_CGU->PLL1_STAT&1)){ /* Locked? */
|
||||
ClkSrc = (LPC_CGU->PLL1_CTRL & CGU_CTRL_SRC_MASK)>>24;
|
||||
CGU_ClockSourceFrequency[CGU_CLKSRC_PLL1] = CGU_ClockSourceFrequency[ClkSrc] *
|
||||
(((LPC_CGU->PLL1_CTRL>>16)&0xFF)+1);
|
||||
}else
|
||||
CGU_ClockSourceFrequency[CGU_CLKSRC_PLL1] = 0;
|
||||
|
||||
/* DIV */
|
||||
for(div = CGU_CLKSRC_IDIVA; div <= CGU_CLKSRC_IDIVE; div++){
|
||||
RegOffset = CGU_Entity_ControlReg_Offset[div];
|
||||
if(ISBITCLR(CGU_ADDRESS32(LPC_CGU,RegOffset),1)){
|
||||
ClkSrc = (CGU_ADDRESS32(LPC_CGU,RegOffset) & CGU_CTRL_SRC_MASK) >> 24;
|
||||
divisor = (CGU_ADDRESS32(LPC_CGU,RegOffset)>>2) & 0xFF;
|
||||
divisor ++;
|
||||
CGU_ClockSourceFrequency[div] = CGU_ClockSourceFrequency[ClkSrc] / divisor;
|
||||
}else
|
||||
CGU_ClockSourceFrequency[div] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set XTAL oscillator value
|
||||
* @param[in] ClockFrequency XTAL Frequency value
|
||||
* @return Setting status, could be:
|
||||
* - CGU_ERROR_SUCCESS: successful
|
||||
* - CGU_ERROR_FREQ_OUTOF_RANGE: XTAL value set is out of range
|
||||
**********************************************************************/
|
||||
uint32_t CGU_SetXTALOSC(uint32_t ClockFrequency){
|
||||
if(ClockFrequency < 15000000){
|
||||
LPC_CGU->XTAL_OSC_CTRL &= ~(1<<2);
|
||||
}else if(ClockFrequency < 25000000){
|
||||
LPC_CGU->XTAL_OSC_CTRL |= (1<<2);
|
||||
}else
|
||||
return CGU_ERROR_FREQ_OUTOF_RANGE;
|
||||
|
||||
CGU_ClockSourceFrequency[CGU_CLKSRC_XTAL_OSC] = ClockFrequency;
|
||||
return CGU_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set clock divider
|
||||
* @param[in] SelectDivider Clock source, should be:
|
||||
* - CGU_CLKSRC_IDIVA :Integer divider register A
|
||||
* - CGU_CLKSRC_IDIVB :Integer divider register B
|
||||
* - CGU_CLKSRC_IDIVC :Integer divider register C
|
||||
* - CGU_CLKSRC_IDIVD :Integer divider register D
|
||||
* - CGU_CLKSRC_IDIVE :Integer divider register E
|
||||
* @param[in] divisor Divisor value, should be: 0..255
|
||||
* @return Setting status, could be:
|
||||
* - CGU_ERROR_SUCCESS: successful
|
||||
* - CGU_ERROR_INVALID_ENTITY: Invalid entity
|
||||
**********************************************************************/
|
||||
/* divisor number must >=1*/
|
||||
uint32_t CGU_SetDIV(CGU_ENTITY_T SelectDivider, uint32_t divisor){
|
||||
int32_t RegOffset;
|
||||
uint32_t tempReg;
|
||||
if(SelectDivider>=CGU_CLKSRC_IDIVA && SelectDivider<=CGU_CLKSRC_IDIVE){
|
||||
RegOffset = CGU_Entity_ControlReg_Offset[SelectDivider];
|
||||
if(RegOffset == -1) return CGU_ERROR_INVALID_ENTITY;
|
||||
tempReg = CGU_ADDRESS32(LPC_CGU,RegOffset);
|
||||
tempReg &= ~(0xFF<<2);
|
||||
tempReg |= ((divisor-1)&0xFF)<<2;
|
||||
CGU_ADDRESS32(LPC_CGU,RegOffset) = tempReg;
|
||||
return CGU_ERROR_SUCCESS;
|
||||
}
|
||||
return CGU_ERROR_INVALID_ENTITY;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable clock entity
|
||||
* @param[in] ClockEntity Clock entity, should be:
|
||||
* - CGU_CLKSRC_32KHZ_OSC :32Khz oscillator
|
||||
* - CGU_CLKSRC_IRC :IRC clock
|
||||
* - CGU_CLKSRC_ENET_RX_CLK :Ethernet receive clock
|
||||
* - CGU_CLKSRC_ENET_TX_CLK :Ethernet transmit clock
|
||||
* - CGU_CLKSRC_GP_CLKIN :General purpose input clock
|
||||
* - CGU_CLKSRC_XTAL_OSC :Crystal oscillator
|
||||
* - CGU_CLKSRC_PLL0 :PLL0 clock
|
||||
* - CGU_CLKSRC_PLL1 :PLL1 clock
|
||||
* - CGU_CLKSRC_IDIVA :Integer divider register A
|
||||
* - CGU_CLKSRC_IDIVB :Integer divider register B
|
||||
* - CGU_CLKSRC_IDIVC :Integer divider register C
|
||||
* - CGU_CLKSRC_IDIVD :Integer divider register D
|
||||
* - CGU_CLKSRC_IDIVE :Integer divider register E
|
||||
* - CGU_BASE_SAFE :Base safe clock (always on)for WDT
|
||||
* - CGU_BASE_USB0 :Base clock for USB0
|
||||
* - CGU_BASE_PERIPH :Base clock for Peripheral bus
|
||||
* - CGU_BASE_USB1 :Base clock for USB1
|
||||
* - CGU_BASE_M4 :System base clock for ARM Cortex-M3 core
|
||||
* and APB peripheral blocks #0 and #2
|
||||
* - CGU_BASE_SPIFI :Base clock for SPIFI
|
||||
* - CGU_BASE_PHY_RX :Base clock for Ethernet PHY Rx
|
||||
* - CGU_BASE_PHY_TX :Base clock for Ethernet PHY Tx
|
||||
* - CGU_BASE_APB1 :Base clock for APB peripheral block #1
|
||||
* - CGU_BASE_APB3 :Base clock for APB peripheral block #3
|
||||
* - CGU_BASE_LCD :Base clock for LCD
|
||||
* - CGU_BASE_SDIO :Base clock for SDIO card reader
|
||||
* - CGU_BASE_SSP0 :Base clock for SSP0
|
||||
* - CGU_BASE_SSP1 :Base clock for SSP1
|
||||
* - CGU_BASE_UART0 :Base clock for UART0
|
||||
* - CGU_BASE_UART1 :Base clock for UART1
|
||||
* - CGU_BASE_UART2 :Base clock for UART2
|
||||
* - CGU_BASE_UART3 :Base clock for UART3
|
||||
* - CGU_BASE_CLKOUT :Base clock for CLKOUT pin
|
||||
* @param[in] en status, should be:
|
||||
* - ENABLE: Enable power
|
||||
* - DISABLE: Disable power
|
||||
* @return Setting status, could be:
|
||||
* - CGU_ERROR_SUCCESS: successful
|
||||
* - CGU_ERROR_INVALID_ENTITY: Invalid entity
|
||||
**********************************************************************/
|
||||
uint32_t CGU_EnableEntity(CGU_ENTITY_T ClockEntity, uint32_t en){
|
||||
int32_t RegOffset;
|
||||
int32_t i;
|
||||
if(ClockEntity == CGU_CLKSRC_32KHZ_OSC){
|
||||
if(en){
|
||||
LPC_CREG->CREG0 &= ~((1<<3)|(1<<2));
|
||||
LPC_CREG->CREG0 |= (1<<1)|(1<<0);
|
||||
}else{
|
||||
LPC_CREG->CREG0 &= ~((1<<1)|(1<<0));
|
||||
LPC_CREG->CREG0 |= (1<<3);
|
||||
}
|
||||
for(i = 0;i<1000000;i++);
|
||||
|
||||
}else if(ClockEntity == CGU_CLKSRC_ENET_RX_CLK){
|
||||
scu_pinmux(0xC ,0 , MD_PLN, FUNC3);
|
||||
|
||||
}else if(ClockEntity == CGU_CLKSRC_ENET_TX_CLK){
|
||||
scu_pinmux(0x1 ,19 , MD_PLN, FUNC0);
|
||||
|
||||
}else if(ClockEntity == CGU_CLKSRC_GP_CLKIN){
|
||||
|
||||
}else if(ClockEntity == CGU_CLKSRC_TCK){
|
||||
|
||||
}else if(ClockEntity == CGU_CLKSRC_XTAL_OSC){
|
||||
if(!en)
|
||||
LPC_CGU->XTAL_OSC_CTRL |= CGU_CTRL_EN_MASK;
|
||||
else
|
||||
LPC_CGU->XTAL_OSC_CTRL &= ~CGU_CTRL_EN_MASK;
|
||||
/*Delay for stable clock*/
|
||||
for(i = 0;i<1000000;i++);
|
||||
|
||||
}else{
|
||||
RegOffset = CGU_Entity_ControlReg_Offset[ClockEntity];
|
||||
if(RegOffset == -1) return CGU_ERROR_INVALID_ENTITY;
|
||||
if(!en){
|
||||
CGU_ADDRESS32(CGU_CGU_ADDR,RegOffset) |= CGU_CTRL_EN_MASK;
|
||||
}else{
|
||||
CGU_ADDRESS32(CGU_CGU_ADDR,RegOffset) &= ~CGU_CTRL_EN_MASK;
|
||||
/*if PLL is selected check if it is locked */
|
||||
if(ClockEntity == CGU_CLKSRC_PLL0){
|
||||
while((LPC_CGU->PLL0USB_STAT&1) == 0x0);
|
||||
}
|
||||
if(ClockEntity == CGU_CLKSRC_PLL0_AUDIO){
|
||||
while((LPC_CGU->PLL0AUDIO_STAT&1) == 0x0);
|
||||
}
|
||||
if(ClockEntity == CGU_CLKSRC_PLL1){
|
||||
while((LPC_CGU->PLL1_STAT&1) == 0x0);
|
||||
/*post check lock status */
|
||||
if(!(LPC_CGU->PLL1_STAT&1))
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return CGU_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Connect entity clock source
|
||||
* @param[in] ClockSource Clock source, should be:
|
||||
* - CGU_CLKSRC_32KHZ_OSC :32Khz oscillator
|
||||
* - CGU_CLKSRC_IRC :IRC clock
|
||||
* - CGU_CLKSRC_ENET_RX_CLK :Ethernet receive clock
|
||||
* - CGU_CLKSRC_ENET_TX_CLK :Ethernet transmit clock
|
||||
* - CGU_CLKSRC_GP_CLKIN :General purpose input clock
|
||||
* - CGU_CLKSRC_XTAL_OSC :Crystal oscillator
|
||||
* - CGU_CLKSRC_PLL0 :PLL0 clock
|
||||
* - CGU_CLKSRC_PLL1 :PLL1 clock
|
||||
* - CGU_CLKSRC_IDIVA :Integer divider register A
|
||||
* - CGU_CLKSRC_IDIVB :Integer divider register B
|
||||
* - CGU_CLKSRC_IDIVC :Integer divider register C
|
||||
* - CGU_CLKSRC_IDIVD :Integer divider register D
|
||||
* - CGU_CLKSRC_IDIVE :Integer divider register E
|
||||
* @param[in] ClockEntity Clock entity, should be:
|
||||
* - CGU_CLKSRC_PLL0 :PLL0 clock
|
||||
* - CGU_CLKSRC_PLL1 :PLL1 clock
|
||||
* - CGU_CLKSRC_IDIVA :Integer divider register A
|
||||
* - CGU_CLKSRC_IDIVB :Integer divider register B
|
||||
* - CGU_CLKSRC_IDIVC :Integer divider register C
|
||||
* - CGU_CLKSRC_IDIVD :Integer divider register D
|
||||
* - CGU_CLKSRC_IDIVE :Integer divider register E
|
||||
* - CGU_BASE_SAFE :Base safe clock (always on)for WDT
|
||||
* - CGU_BASE_USB0 :Base clock for USB0
|
||||
* - CGU_BASE_USB1 :Base clock for USB1
|
||||
* - CGU_BASE_M4 :System base clock for ARM Cortex-M3 core
|
||||
* and APB peripheral blocks #0 and #2
|
||||
* - CGU_BASE_SPIFI :Base clock for SPIFI
|
||||
* - CGU_BASE_PHY_RX :Base clock for Ethernet PHY Rx
|
||||
* - CGU_BASE_PHY_TX :Base clock for Ethernet PHY Tx
|
||||
* - CGU_BASE_APB1 :Base clock for APB peripheral block #1
|
||||
* - CGU_BASE_APB3 :Base clock for APB peripheral block #3
|
||||
* - CGU_BASE_LCD :Base clock for LCD
|
||||
* - CGU_BASE_SDIO :Base clock for SDIO card reader
|
||||
* - CGU_BASE_SSP0 :Base clock for SSP0
|
||||
* - CGU_BASE_SSP1 :Base clock for SSP1
|
||||
* - CGU_BASE_UART0 :Base clock for UART0
|
||||
* - CGU_BASE_UART1 :Base clock for UART1
|
||||
* - CGU_BASE_UART2 :Base clock for UART2
|
||||
* - CGU_BASE_UART3 :Base clock for UART3
|
||||
* - CGU_BASE_CLKOUT :Base clock for CLKOUT pin
|
||||
* @return Setting status, could be:
|
||||
* - CGU_ERROR_SUCCESS: successful
|
||||
* - CGU_ERROR_CONNECT_TOGETHER: Error when 2 clock source connect together
|
||||
* - CGU_ERROR_INVALID_CLOCK_SOURCE: Invalid clock source error
|
||||
* - CGU_ERROR_INVALID_ENTITY: Invalid entity error
|
||||
**********************************************************************/
|
||||
/* Connect one entity into clock source */
|
||||
uint32_t CGU_EntityConnect(CGU_ENTITY_T ClockSource, CGU_ENTITY_T ClockEntity){
|
||||
int32_t RegOffset;
|
||||
uint32_t tempReg;
|
||||
|
||||
if(ClockSource > CGU_CLKSRC_IDIVE)
|
||||
return CGU_ERROR_INVALID_CLOCK_SOURCE;
|
||||
|
||||
if(ClockEntity >= CGU_CLKSRC_PLL0 && ClockEntity <= CGU_BASE_CLKOUT){
|
||||
if(CGU_ConnectAlloc_Tbl[ClockSource][ClockEntity]){
|
||||
RegOffset = CGU_Entity_ControlReg_Offset[ClockSource];
|
||||
if(RegOffset != -1){
|
||||
if(ClockEntity<=CGU_CLKSRC_IDIVE &&
|
||||
ClockEntity>=CGU_CLKSRC_PLL0)
|
||||
{
|
||||
//RegOffset = (CGU_ADDRESS32(LPC_CGU,RegOffset)>>24)&0xF;
|
||||
if(((CGU_ADDRESS32(LPC_CGU,RegOffset)>>24)& 0xF) == ClockEntity)
|
||||
return CGU_ERROR_CONNECT_TOGETHER;
|
||||
}
|
||||
}
|
||||
RegOffset = CGU_Entity_ControlReg_Offset[ClockEntity];
|
||||
if(RegOffset == -1) return CGU_ERROR_INVALID_ENTITY;
|
||||
tempReg = CGU_ADDRESS32(LPC_CGU,RegOffset);
|
||||
tempReg &= ~CGU_CTRL_SRC_MASK;
|
||||
tempReg |= ClockSource<<24 | CGU_CTRL_AUTOBLOCK_MASK;
|
||||
CGU_ADDRESS32(LPC_CGU,RegOffset) = tempReg;
|
||||
return CGU_ERROR_SUCCESS;
|
||||
}else
|
||||
return CGU_ERROR_INVALID_CLOCK_SOURCE;
|
||||
}else
|
||||
return CGU_ERROR_INVALID_ENTITY;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get current USB PLL clock from XTAL
|
||||
* @param[in] None
|
||||
* @return Returned clock value
|
||||
**********************************************************************/
|
||||
uint32_t CGU_SetPLL0(void){
|
||||
// Setup PLL550 to generate 480MHz from 12 MHz crystal
|
||||
LPC_CGU->PLL0USB_CTRL |= 1; // Power down PLL
|
||||
// P N
|
||||
LPC_CGU->PLL0USB_NP_DIV = (98<<0) | (514<<12);
|
||||
// SELP SELI SELR MDEC
|
||||
LPC_CGU->PLL0USB_MDIV = (0xB<<17)|(0x10<<22)|(0<<28)|(0x7FFA<<0);
|
||||
LPC_CGU->PLL0USB_CTRL =(CGU_CLKSRC_XTAL_OSC<<24) | (0x3<<2) | (1<<4);
|
||||
return CGU_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get current Audio PLL clock from XTAL
|
||||
* @param[in] None
|
||||
* @return Returned clock value
|
||||
**********************************************************************/
|
||||
uint32_t CGU_SetPLL0audio(void){
|
||||
/* disable clock, disable skew enable, power down pll,
|
||||
* (dis/en)able post divider, (dis/en)able pre-divider,
|
||||
* disable free running mode, disable bandsel,
|
||||
* enable up limmiter, disable bypass
|
||||
*/
|
||||
LPC_CGU->PLL0AUDIO_CTRL = (6 << 24) /* source = XTAL OSC 12 MHz */
|
||||
| _BIT(0); /* power down */
|
||||
/* PLL should be set to 512fs rate 512 * 48000 = 24576000 Hz */
|
||||
/* set mdec register */
|
||||
#if 1 // results from gcc program
|
||||
LPC_CGU->PLL0AUDIO_MDIV = 0x23e34d3;
|
||||
LPC_CGU->PLL0AUDIO_NP_DIV = 0x3f00e;
|
||||
LPC_CGU->PLL0AUDIO_CTRL = (6 << 24) /* source = XTAL OSC 12 MHz */
|
||||
| (6<< 12) // fractional divider off and bypassed
|
||||
| _BIT(4); /* CLKEN */
|
||||
#else
|
||||
LPC_CGU->PLL0AUDIO_MDIV = (0 << 28) /* SELR */
|
||||
| (40 << 22) /* SELI */
|
||||
| (31 << 17) /* SELP */
|
||||
| 11372; /* MDEC */
|
||||
/* set ndec, pdec register */
|
||||
LPC_CGU->PLL0AUDIO_NP_DIV = (22 << 12) /* ndec */
|
||||
| (10); /* pdec */
|
||||
|
||||
/* set fraction divider register. [21:15] = m, [14:0] = fractional value */
|
||||
LPC_CGU->PLL0AUDIO_FRAC = (86 << 15) | 0x1B7;
|
||||
LPC_CGU->PLL0AUDIO_CTRL = (6 << 24) /* source = XTAL OSC 12 MHz */
|
||||
| _BIT(12) /* enable SD modulator to update mdec*/
|
||||
| _BIT(4); /* CLKEN */
|
||||
#endif
|
||||
/* wait for lock */
|
||||
while (!(LPC_CGU->PLL0AUDIO_STAT & 1));
|
||||
|
||||
return CGU_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Setting PLL1
|
||||
* @param[in] mult Multiple value
|
||||
* @return Setting status, could be:
|
||||
* - CGU_ERROR_SUCCESS: successful
|
||||
* - CGU_ERROR_INVALID_PARAM: Invalid parameter error
|
||||
**********************************************************************/
|
||||
uint32_t CGU_SetPLL1(uint32_t mult){
|
||||
uint32_t msel=0, nsel=0, psel=0, pval=1;
|
||||
uint32_t freq;
|
||||
uint32_t ClkSrc = (LPC_CGU->PLL1_CTRL & CGU_CTRL_SRC_MASK)>>24;
|
||||
freq = CGU_ClockSourceFrequency[ClkSrc];
|
||||
freq *= mult;
|
||||
msel = mult-1;
|
||||
|
||||
LPC_CGU->PLL1_CTRL &= ~(CGU_PLL1_FBSEL_MASK |
|
||||
CGU_PLL1_BYPASS_MASK |
|
||||
CGU_PLL1_DIRECT_MASK |
|
||||
(0x03<<8) | (0xFF<<16) | (0x03<<12));
|
||||
|
||||
if(freq<156000000){
|
||||
//psel is encoded such that 0=1, 1=2, 2=4, 3=8
|
||||
while(2*(pval)*freq < 156000000) {
|
||||
psel++;
|
||||
pval*=2;
|
||||
}
|
||||
// if(2*(pval)*freq > 320000000) {
|
||||
// //THIS IS OUT OF RANGE!!!
|
||||
// //HOW DO WE ASSERT IN SAMPLE CODE?
|
||||
// //__breakpoint(0);
|
||||
// return CGU_ERROR_INVALID_PARAM;
|
||||
// }
|
||||
LPC_CGU->PLL1_CTRL |= (msel<<16) | (nsel<<12) | (psel<<8) | CGU_PLL1_FBSEL_MASK;
|
||||
}else if(freq<320000000){
|
||||
LPC_CGU->PLL1_CTRL |= (msel<<16) | (nsel<<12) | (psel<<8) |CGU_PLL1_DIRECT_MASK | CGU_PLL1_FBSEL_MASK;
|
||||
}else
|
||||
return CGU_ERROR_INVALID_PARAM;
|
||||
|
||||
return CGU_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get current base status
|
||||
* @param[in] Base Base type, should be:
|
||||
* - CGU_BASE_USB0 :Base clock for USB0
|
||||
* - CGU_BASE_USB1 :Base clock for USB1
|
||||
* - CGU_BASE_M4 :System base clock for ARM Cortex-M3 core
|
||||
* and APB peripheral blocks #0 and #2
|
||||
* - CGU_BASE_SPIFI :Base clock for SPIFI
|
||||
* - CGU_BASE_APB1 :Base clock for APB peripheral block #1
|
||||
* - CGU_BASE_APB3 :Base clock for APB peripheral block #3
|
||||
* - CGU_BASE_SDIO :Base clock for SDIO card reader
|
||||
* - CGU_BASE_SSP0 :Base clock for SSP0
|
||||
* - CGU_BASE_SSP1 :Base clock for SSP1
|
||||
* - CGU_BASE_UART0 :Base clock for UART0
|
||||
* - CGU_BASE_UART1 :Base clock for UART1
|
||||
* - CGU_BASE_UART2 :Base clock for UART2
|
||||
* - CGU_BASE_UART3 :Base clock for UART3
|
||||
* @return Always return 0
|
||||
**********************************************************************/
|
||||
uint32_t CGU_GetBaseStatus(CGU_ENTITY_T Base){
|
||||
switch(Base){
|
||||
/*CCU1*/
|
||||
case CGU_BASE_APB3:
|
||||
return LPC_CCU1->BASE_STAT & 1;
|
||||
|
||||
case CGU_BASE_APB1:
|
||||
return (LPC_CCU1->BASE_STAT>>1) & 1;
|
||||
|
||||
case CGU_BASE_SPIFI:
|
||||
return (LPC_CCU1->BASE_STAT>>2) & 1;
|
||||
|
||||
case CGU_BASE_M4:
|
||||
return (LPC_CCU1->BASE_STAT>>3) & 1;
|
||||
|
||||
case CGU_BASE_USB0:
|
||||
return (LPC_CCU1->BASE_STAT>>7) & 1;
|
||||
|
||||
case CGU_BASE_USB1:
|
||||
return (LPC_CCU1->BASE_STAT>>8) & 1;
|
||||
|
||||
/*CCU2*/
|
||||
case CGU_BASE_UART3:
|
||||
return (LPC_CCU2->BASE_STAT>>1) & 1;
|
||||
|
||||
case CGU_BASE_UART2:
|
||||
return (LPC_CCU2->BASE_STAT>>2) & 1;
|
||||
|
||||
case CGU_BASE_UART1:
|
||||
return (LPC_CCU2->BASE_STAT>>3) & 1;
|
||||
|
||||
case CGU_BASE_UART0:
|
||||
return (LPC_CCU2->BASE_STAT>>4) & 1;
|
||||
|
||||
case CGU_BASE_SSP1:
|
||||
return (LPC_CCU2->BASE_STAT>>5) & 1;
|
||||
|
||||
case CGU_BASE_SSP0:
|
||||
return (LPC_CCU2->BASE_STAT>>6) & 1;
|
||||
|
||||
case CGU_BASE_SDIO:
|
||||
return (LPC_CCU2->BASE_STAT>>7) & 1;
|
||||
|
||||
/*BASE SAFE is used by WWDT and RGU*/
|
||||
case CGU_BASE_SAFE:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Compare one source clock to IRC clock
|
||||
* @param[in] Clock Clock entity that will be compared to IRC, should be:
|
||||
* - CGU_CLKSRC_32KHZ_OSC :32Khz crystal oscillator
|
||||
* - CGU_CLKSRC_ENET_RX_CLK :Ethernet receive clock
|
||||
* - CGU_CLKSRC_ENET_TX_CLK :Ethernet transmit clock
|
||||
* - CGU_CLKSRC_GP_CLKIN :General purpose input clock
|
||||
* - CGU_CLKSRC_XTAL_OSC :Crystal oscillator
|
||||
* - CGU_CLKSRC_PLL0 :PLL0 clock
|
||||
* - CGU_CLKSRC_PLL1 :PLL1 clock
|
||||
* - CGU_CLKSRC_IDIVA :Integer divider register A
|
||||
* - CGU_CLKSRC_IDIVB :Integer divider register B
|
||||
* - CGU_CLKSRC_IDIVC :Integer divider register C
|
||||
* - CGU_CLKSRC_IDIVD :Integer divider register D
|
||||
* - CGU_CLKSRC_IDIVE :Integer divider register E
|
||||
* - CGU_BASE_SAFE :Base safe clock (always on)for WDT
|
||||
* - CGU_BASE_USB0 :Base clock for USB0
|
||||
* - CGU_BASE_USB1 :Base clock for USB1
|
||||
* - CGU_BASE_M4 :System base clock for ARM Cortex-M3 core
|
||||
* and APB peripheral blocks #0 and #2
|
||||
* - CGU_BASE_SPIFI :Base clock for SPIFI
|
||||
* - CGU_BASE_PHY_RX :Base clock for Ethernet PHY Rx
|
||||
* - CGU_BASE_PHY_TX :Base clock for Ethernet PHY Tx
|
||||
* - CGU_BASE_APB1 :Base clock for APB peripheral block #1
|
||||
* - CGU_BASE_APB3 :Base clock for APB peripheral block #3
|
||||
* - CGU_BASE_LCD :Base clock for LCD
|
||||
* - CGU_BASE_SDIO :Base clock for SDIO card reader
|
||||
* - CGU_BASE_SSP0 :Base clock for SSP0
|
||||
* - CGU_BASE_SSP1 :Base clock for SSP1
|
||||
* - CGU_BASE_UART0 :Base clock for UART0
|
||||
* - CGU_BASE_UART1 :Base clock for UART1
|
||||
* - CGU_BASE_UART2 :Base clock for UART2
|
||||
* - CGU_BASE_UART3 :Base clock for UART3
|
||||
* - CGU_BASE_CLKOUT :Base clock for CLKOUT pin
|
||||
* @param[in] m Multiple value pointer
|
||||
* @param[in] d Divider value pointer
|
||||
* @return Compare status, could be:
|
||||
* - (-1): fail
|
||||
* - 0: successful
|
||||
* @note Formula used to compare:
|
||||
* FClock = F_IRC* m / d
|
||||
**********************************************************************/
|
||||
int CGU_FrequencyMonitor(CGU_ENTITY_T Clock, uint32_t *m, uint32_t *d){
|
||||
uint32_t n,c,temp;
|
||||
int i;
|
||||
|
||||
/* Maximum allow RCOUNT number */
|
||||
c= 511;
|
||||
/* Check Source Clock Freq is larger or smaller */
|
||||
LPC_CGU->FREQ_MON = (Clock<<24) | 1<<23 | c;
|
||||
while(LPC_CGU->FREQ_MON & (1 <<23));
|
||||
for(i=0;i<10000;i++);
|
||||
temp = (LPC_CGU->FREQ_MON >>9) & 0x3FFF;
|
||||
|
||||
if(temp == 0) /* too low F < 12000000/511*/
|
||||
return -1;
|
||||
if(temp > 511){ /* larger */
|
||||
|
||||
c = 511 - (LPC_CGU->FREQ_MON&0x1FF);
|
||||
}else{
|
||||
do{
|
||||
c--;
|
||||
LPC_CGU->FREQ_MON = (Clock<<24) | 1<<23 | c;
|
||||
while(LPC_CGU->FREQ_MON & (1 <<23));
|
||||
for(i=0;i<10000;i++);
|
||||
n = (LPC_CGU->FREQ_MON >>9) & 0x3FFF;
|
||||
}while(n==temp);
|
||||
c++;
|
||||
}
|
||||
*m = temp;
|
||||
*d = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Compare one source clock to another source clock
|
||||
* @param[in] Clock Clock entity that will be compared to second source, should be:
|
||||
* - CGU_CLKSRC_32KHZ_OSC :32Khz crystal oscillator
|
||||
* - CGU_CLKSRC_ENET_RX_CLK :Ethernet receive clock
|
||||
* - CGU_CLKSRC_ENET_TX_CLK :Ethernet transmit clock
|
||||
* - CGU_CLKSRC_GP_CLKIN :General purpose input clock
|
||||
* - CGU_CLKSRC_XTAL_OSC :Crystal oscillator
|
||||
* - CGU_CLKSRC_PLL0 :PLL0 clock
|
||||
* - CGU_CLKSRC_PLL1 :PLL1 clock
|
||||
* - CGU_CLKSRC_IDIVA :Integer divider register A
|
||||
* - CGU_CLKSRC_IDIVB :Integer divider register B
|
||||
* - CGU_CLKSRC_IDIVC :Integer divider register C
|
||||
* - CGU_CLKSRC_IDIVD :Integer divider register D
|
||||
* - CGU_CLKSRC_IDIVE :Integer divider register E
|
||||
* - CGU_BASE_SAFE :Base safe clock (always on)for WDT
|
||||
* - CGU_BASE_USB0 :Base clock for USB0
|
||||
* - CGU_BASE_USB1 :Base clock for USB1
|
||||
* - CGU_BASE_M4 :System base clock for ARM Cortex-M3 core
|
||||
* and APB peripheral blocks #0 and #2
|
||||
* - CGU_BASE_SPIFI :Base clock for SPIFI
|
||||
* - CGU_BASE_PHY_RX :Base clock for Ethernet PHY Rx
|
||||
* - CGU_BASE_PHY_TX :Base clock for Ethernet PHY Tx
|
||||
* - CGU_BASE_APB1 :Base clock for APB peripheral block #1
|
||||
* - CGU_BASE_APB3 :Base clock for APB peripheral block #3
|
||||
* - CGU_BASE_LCD :Base clock for LCD
|
||||
* - CGU_BASE_SDIO :Base clock for SDIO card reader
|
||||
* - CGU_BASE_SSP0 :Base clock for SSP0
|
||||
* - CGU_BASE_SSP1 :Base clock for SSP1
|
||||
* - CGU_BASE_UART0 :Base clock for UART0
|
||||
* - CGU_BASE_UART1 :Base clock for UART1
|
||||
* - CGU_BASE_UART2 :Base clock for UART2
|
||||
* - CGU_BASE_UART3 :Base clock for UART3
|
||||
* - CGU_BASE_CLKOUT :Base clock for CLKOUT pin
|
||||
* @param[in] CompareToClock Clock source that to be compared to first source, should be different
|
||||
* to first source.
|
||||
* @param[in] m Multiple value pointer
|
||||
* @param[in] d Divider value pointer
|
||||
* @return Compare status, could be:
|
||||
* - (-1): fail
|
||||
* - 0: successful
|
||||
* @note Formula used to compare:
|
||||
* FClock = m*FCompareToClock/d
|
||||
**********************************************************************/
|
||||
uint32_t CGU_RealFrequencyCompare(CGU_ENTITY_T Clock, CGU_ENTITY_T CompareToClock, uint32_t *m, uint32_t *d){
|
||||
uint32_t m1,m2,d1,d2;
|
||||
/* Check Parameter */
|
||||
if((Clock>CGU_CLKSRC_IDIVE) || (CompareToClock>CGU_CLKSRC_IDIVE))
|
||||
return CGU_ERROR_INVALID_PARAM;
|
||||
/* Check for Clock Enable - Not yet implement
|
||||
* The Comparator will hang if Clock has not been set*/
|
||||
CGU_FrequencyMonitor(Clock, &m1, &d1);
|
||||
CGU_FrequencyMonitor(CompareToClock, &m2, &d2);
|
||||
*m= m1*d2;
|
||||
*d= d1*m2;
|
||||
return 0;
|
||||
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_dac.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_dac.c
|
||||
* @brief Contains all functions support for DAC firmware library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup DAC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_dac.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
|
||||
#ifdef _DAC
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup DAC_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Initial ADC configuration
|
||||
* - Maximum current is 700 uA
|
||||
* - Value to AOUT is 0
|
||||
* @param[in] DACx pointer to LPC_DAC_Type, should be: LPC_DAC
|
||||
* @return None
|
||||
***********************************************************************/
|
||||
void DAC_Init(LPC_DAC_Type *DACx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_DACx(DACx));
|
||||
/* Set default clock divider for DAC */
|
||||
//LPC_CGU->BASE_VPB3_CLK = (SRC_PL160M_0<<24) | (1<<11); // ABP3 base clock use PLL1 and auto block
|
||||
CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_APB3);
|
||||
//Set maximum current output
|
||||
DAC_SetBias(LPC_DAC,DAC_MAX_CURRENT_700uA);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Update value to DAC
|
||||
* @param[in] DACx pointer to LPC_DAC_Type, should be: LPC_DAC
|
||||
* @param[in] dac_value value 10 bit to be converted to output
|
||||
* @return None
|
||||
***********************************************************************/
|
||||
void DAC_UpdateValue (LPC_DAC_Type *DACx,uint32_t dac_value)
|
||||
{
|
||||
uint32_t tmp;
|
||||
CHECK_PARAM(PARAM_DACx(DACx));
|
||||
tmp = DACx->CR & DAC_BIAS_EN;
|
||||
tmp |= DAC_VALUE(dac_value);
|
||||
// Update value
|
||||
DACx->CR = tmp;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set Maximum current for DAC
|
||||
* @param[in] DACx pointer to LPC_DAC_Type, should be: LPC_DAC
|
||||
* @param[in] bias Using Bias value, should be:
|
||||
* - 0 is 700 uA
|
||||
* - 1 is 350 uA
|
||||
* @return None
|
||||
***********************************************************************/
|
||||
void DAC_SetBias (LPC_DAC_Type *DACx,uint32_t bias)
|
||||
{
|
||||
CHECK_PARAM(PARAM_DAC_CURRENT_OPT(bias));
|
||||
DACx->CR &=~DAC_BIAS_EN;
|
||||
if (bias == DAC_MAX_CURRENT_350uA)
|
||||
{
|
||||
DACx->CR |= DAC_BIAS_EN;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief To enable the DMA operation and control DMA timer
|
||||
* @param[in] DACx pointer to LPC_DAC_Type, should be: LPC_DAC
|
||||
* @param[in] DAC_ConverterConfigStruct pointer to DAC_CONVERTER_CFG_Type
|
||||
* - DBLBUF_ENA :enable/disable DACR double buffering feature
|
||||
* - CNT_ENA :enable/disable timer out counter
|
||||
* - DMA_ENA :enable/disable DMA access
|
||||
* @return None
|
||||
***********************************************************************/
|
||||
void DAC_ConfigDAConverterControl (LPC_DAC_Type *DACx,DAC_CONVERTER_CFG_Type *DAC_ConverterConfigStruct)
|
||||
{
|
||||
CHECK_PARAM(PARAM_DACx(DACx));
|
||||
DACx->CTRL &= ~DAC_DACCTRL_MASK;
|
||||
if (DAC_ConverterConfigStruct->DBLBUF_ENA)
|
||||
DACx->CTRL |= DAC_DBLBUF_ENA;
|
||||
if (DAC_ConverterConfigStruct->CNT_ENA)
|
||||
DACx->CTRL |= DAC_CNT_ENA;
|
||||
if (DAC_ConverterConfigStruct->DMA_ENA)
|
||||
DACx->CTRL |= DAC_DMA_ENA;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set reload value for interrupt/DMA counter
|
||||
* @param[in] DACx pointer to LPC_DAC_Type, should be: LPC_DAC
|
||||
* @param[in] time_out time out to reload for interrupt/DMA counter
|
||||
* @return None
|
||||
***********************************************************************/
|
||||
void DAC_SetDMATimeOut(LPC_DAC_Type *DACx, uint32_t time_out)
|
||||
{
|
||||
CHECK_PARAM(PARAM_DACx(DACx));
|
||||
DACx->CNTVAL = DAC_CCNT_VALUE(time_out);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _DAC */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
/**********************************************************************
|
||||
* $Id: lpc43xx_emc.c 8765 2011-12-08 00:51:21Z nxp21346 $ lpc43xx_emc.c 2011-12-07
|
||||
*//**
|
||||
* @file lpc43xx_emc.c
|
||||
* @brief Contains all functions support for Clock Generation and Control
|
||||
* firmware library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 07. December. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
#include "LPC43xx.h"
|
||||
#include "lpc43xx_emc.h"
|
||||
#include "lpc43xx_scu.h"
|
||||
|
||||
#define M32(x) *((uint32_t *)x)
|
||||
#define DELAYCYCLES(ns) (ns / ((1.0 / __EMCHZ) * 1E9))
|
||||
|
||||
void emc_WaitUS(volatile uint32_t us)
|
||||
{
|
||||
us *= (SystemCoreClock / 1000000) / 3;
|
||||
while(us--);
|
||||
}
|
||||
|
||||
void emc_WaitMS(uint32_t ms)
|
||||
{
|
||||
emc_WaitUS(ms * 1000);
|
||||
}
|
||||
|
||||
void MemoryPinInit(void)
|
||||
{
|
||||
/* select correct functions on the GPIOs */
|
||||
|
||||
#if 1
|
||||
/* DATA LINES 0..31 > D0..D31 */
|
||||
/* P1_7 - EXTBUS_D0 — External memory data line 0 */
|
||||
scu_pinmux(0x1, 7, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P1_7: D0 (function 0) errata */
|
||||
scu_pinmux(0x1, 8, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P1_8: D1 (function 0) errata */
|
||||
scu_pinmux(0x1, 9, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P1_9: D2 (function 0) errata */
|
||||
scu_pinmux(0x1, 10, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P1_10: D3 (function 0) errata */
|
||||
scu_pinmux(0x1, 11, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P1_11: D4 (function 0) errata */
|
||||
scu_pinmux(0x1, 12, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P1_12: D5 (function 0) errata */
|
||||
scu_pinmux(0x1, 13, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P1_13: D6 (function 0) errata */
|
||||
scu_pinmux(0x1, 14, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P1_14: D7 (function 0) errata */
|
||||
scu_pinmux(0x5, 4, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P5_4: D8 (function 0) errata */
|
||||
scu_pinmux(0x5, 5, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P5_5: D9 (function 0) errata */
|
||||
scu_pinmux(0x5, 6, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P5_6: D10 (function 0) errata */
|
||||
scu_pinmux(0x5, 7, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P5_7: D11 (function 0) errata */
|
||||
scu_pinmux(0x5, 0, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P5_0: D12 (function 0) errata */
|
||||
scu_pinmux(0x5, 1, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P5_1: D13 (function 0) errata */
|
||||
scu_pinmux(0x5, 2, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P5_2: D14 (function 0) errata */
|
||||
scu_pinmux(0x5, 3, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P5_3: D15 (function 0) errata */
|
||||
#if 0
|
||||
scu_pinmux(0xD, 2, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* PD_2: D16 (function 0) errata */
|
||||
scu_pinmux(0xD, 3, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* PD_3: D17 (function 0) errata */
|
||||
scu_pinmux(0xD, 4, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* PD_4: D18 (function 0) errata */
|
||||
scu_pinmux(0xD, 5, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* PD_5: D19 (function 0) errata */
|
||||
scu_pinmux(0xD, 6, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* PD_6: D20 (function 0) errata */
|
||||
scu_pinmux(0xD, 7, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* PD_7: D21 (function 0) errata */
|
||||
scu_pinmux(0xD, 8, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* PD_8: D22 (function 0) errata */
|
||||
scu_pinmux(0xD, 9, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* PD_9: D23 (function 0) errata */
|
||||
scu_pinmux(0xE, 5, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PE_5: D24 (function 0) errata */
|
||||
scu_pinmux(0xE, 6, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PE_6: D25 (function 0) errata */
|
||||
scu_pinmux(0xE, 7, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PE_7: D26 (function 0) errata */
|
||||
scu_pinmux(0xE, 8, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PE_8: D27 (function 0) errata */
|
||||
scu_pinmux(0xE, 9, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PE_9: D28 (function 0) errata */
|
||||
scu_pinmux(0xE, 10, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PE_10: D29 (function 0) errata */
|
||||
scu_pinmux(0xE, 11, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PE_11: D30 (function 0) errata */
|
||||
scu_pinmux(0xE, 12, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PE_12: D31 (function 0) errata */
|
||||
#endif
|
||||
|
||||
/* ADDRESS LINES A0..A11 > A0..A11 */
|
||||
scu_pinmux(0x2, 9, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P2_9 - EXTBUS_A0 — External memory address line 0 */
|
||||
scu_pinmux(0x2, 10, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P2_10 - EXTBUS_A1 — External memory address line 1 */
|
||||
scu_pinmux(0x2, 11, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P2_11 - EXTBUS_A2 — External memory address line 2 */
|
||||
scu_pinmux(0x2, 12, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P2_12 - EXTBUS_A3 — External memory address line 3 */
|
||||
scu_pinmux(0x2, 13, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P2_13 - EXTBUS_A4 — External memory address line 4 */
|
||||
scu_pinmux(0x1, 0, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P1_0 - EXTBUS_A5 — External memory address line 5 */
|
||||
scu_pinmux(0x1, 1, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P1_1 - EXTBUS_A6 — External memory address line 6 */
|
||||
scu_pinmux(0x1, 2, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P1_2 - EXTBUS_A7 — External memory address line 7 */
|
||||
scu_pinmux(0x2, 8, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P2_8 - EXTBUS_A8 — External memory address line 8 */
|
||||
scu_pinmux(0x2, 7, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P2_7 - EXTBUS_A9 — External memory address line 9 */
|
||||
scu_pinmux(0x2, 6, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P2_6 - EXTBUS_A10 — External memory address line 10 */
|
||||
scu_pinmux(0x2, 2, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P2_2 - EXTBUS_A11 — External memory address line 11 */
|
||||
scu_pinmux(0x2, 1, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P2_1 - EXTBUS_A12 — External memory address line 12 */
|
||||
scu_pinmux(0x2, 0, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* P2_0 - EXTBUS_A13 — External memory address line 13 */
|
||||
scu_pinmux(0x6, 8, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC1); /* P6_8 - EXTBUS_A14 — External memory address line 14 */
|
||||
scu_pinmux(0x6, 7, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC1); /* P6_7 - EXTBUS_A15 — External memory address line 15 */
|
||||
scu_pinmux(0xD, 16, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* PD_16 - EXTBUS_A16 — External memory address line 16 */
|
||||
scu_pinmux(0xD, 15, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* PD_15 - EXTBUS_A17 — External memory address line 17 */
|
||||
scu_pinmux(0xE, 0, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PE_0 - EXTBUS_A18 — External memory address line 18 */
|
||||
scu_pinmux(0xE, 1, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PE_1 - EXTBUS_A19 — External memory address line 19 */
|
||||
scu_pinmux(0xE, 2, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PE_2 - EXTBUS_A20 — External memory address line 20 */
|
||||
scu_pinmux(0xE, 3, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PE_3 - EXTBUS_A21 — External memory address line 21 */
|
||||
scu_pinmux(0xE, 4, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PE_4 - EXTBUS_A22 — External memory address line 22 */
|
||||
scu_pinmux(0xA, 4, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PA_4 - EXTBUS_A23 — External memory address line 23 */
|
||||
|
||||
/* BYTE ENABLES */
|
||||
scu_pinmux(0x1, 4, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P1_4 - EXTBUS_BLS0 — LOW active Byte Lane select signal 0 */
|
||||
scu_pinmux(0x6, 6, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC1); /* P6_6 - EXTBUS_BLS1 — LOW active Byte Lane select signal 1 */
|
||||
scu_pinmux(0xD, 13, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* PD_13 - EXTBUS_BLS2 — LOW active Byte Lane select signal 2 */
|
||||
scu_pinmux(0xD, 10, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* PD_10 - EXTBUS_BLS3 — LOW active Byte Lane select signal 3 */
|
||||
|
||||
scu_pinmux(0x6, 9, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P6_9: EXTBUS_DYCS0 (function 0) > CS# errata */
|
||||
scu_pinmux(0x1, 6, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P1_6: WE (function 0) errata */
|
||||
scu_pinmux(0x6, 4, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P6_4: CAS (function 0) > CAS# errata */
|
||||
scu_pinmux(0x6, 5, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P6_5: RAS (function 0) > RAS# errata */
|
||||
|
||||
LPC_SCU_CLK(0) = 0 + (MD_PLN | MD_EZI | MD_ZI | MD_EHS); /* SFSCLK0: EXTBUS_CLK0 (function 0, from datasheet) > CLK ds */
|
||||
LPC_SCU_CLK(1) = 0 + (MD_PLN | MD_EZI | MD_ZI | MD_EHS); /* SFSCLK1: EXTBUS_CLK1 (function 2, from datasheet) */
|
||||
LPC_SCU_CLK(2) = 0 + (MD_PLN | MD_EZI | MD_ZI | MD_EHS); /* SFSCLK2: EXTBUS_CLK2 (function 2, from datasheet) */
|
||||
LPC_SCU_CLK(3) = 0 + (MD_PLN | MD_EZI | MD_ZI | MD_EHS); /* SFSCLK3: EXTBUS_CLK3 (function 2, from datasheet) */
|
||||
|
||||
scu_pinmux(0x6, 11, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P6_11: CKEOUT0 (function 0) > CKE errata */
|
||||
scu_pinmux(0x6, 12, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P6_12: DQMOUT0 (function 0) > DQM0 errata */
|
||||
scu_pinmux(0x6, 10, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* P6_10: DQMOUT1 (function 0) > DQM1 errata */
|
||||
scu_pinmux(0xD, 0, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC2); /* PD_0: DQMOUT2 (function 2, from datasheet) > DQM2 errata */
|
||||
scu_pinmux(0xE, 13, (MD_PLN | MD_EZI | MD_ZI | MD_EHS), FUNC3); /* PE_13: DQMOUT3 (function 3, from datasheet) > DQM3 errata */
|
||||
|
||||
scu_pinmux( 1 , 3 , MD_PLN_FAST , 3 ); //OE
|
||||
scu_pinmux( 1 , 4 , MD_PLN_FAST , 3 ); //BLS0
|
||||
scu_pinmux( 1 , 5 , MD_PLN_FAST , 3 ); //CS0
|
||||
scu_pinmux( 1 , 6 , MD_PLN_FAST , 3 ); //WE
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void EMCFlashInit(void)
|
||||
{
|
||||
// Hitex board SST39VF3201B Flash
|
||||
// Read Cycle Time 70 nS minimum
|
||||
// Chip Enable Access Time 70 ns maximum
|
||||
// Address Access Time 70 ns max
|
||||
// Toe 35 ns max
|
||||
// CE/OE high to inactive output 16 ns
|
||||
|
||||
/* Set up EMC Controller */
|
||||
LPC_EMC->STATICWAITRD0 = DELAYCYCLES(70)+1;
|
||||
|
||||
LPC_EMC->STATICWAITPAG0 = DELAYCYCLES(70)+1;
|
||||
|
||||
|
||||
LPC_EMC->CONTROL = 0x01;
|
||||
LPC_EMC->STATICCONFIG0 = (1UL<<7) | (1UL);
|
||||
LPC_EMC->STATICWAITOEN0 = DELAYCYCLES(35)+1;
|
||||
|
||||
/*Enable Buffer for External Flash*/
|
||||
LPC_EMC->STATICCONFIG0 |= 1<<19;
|
||||
}
|
||||
|
||||
/* SDRAM refresh time to 16 clock num */
|
||||
#define EMC_SDRAM_REFRESH(freq,time) \
|
||||
(((uint64_t)((uint64_t)time * freq)/16000000000ull)+1)
|
||||
|
||||
void vEMC_InitSRDRAM(uint32_t u32BaseAddr, uint32_t u32Width, uint32_t u32Size, uint32_t u32DataBus, uint32_t u32ColAddrBits)
|
||||
{
|
||||
// adjust the CCU delaye for EMI (default to zero)
|
||||
//LPC_SCU->EMCCLKDELAY = (CLK0_DELAY | (CLKE0_DELAY << 16));
|
||||
// Move all clock delays together
|
||||
LPC_SCU->EMCDELAYCLK = ((CLK0_DELAY)
|
||||
| (CLK0_DELAY << 4)
|
||||
| (CLK0_DELAY << 8)
|
||||
| (CLK0_DELAY << 12));
|
||||
|
||||
/* Initialize EMC to interface with SDRAM */
|
||||
LPC_EMC->CONTROL = 0x00000001; /* Enable the external memory controller */
|
||||
LPC_EMC->CONFIG = 0;
|
||||
|
||||
LPC_EMC->DYNAMICCONFIG0 = ((u32Width << 7) | (u32Size << 9) | (1UL << 12) | (u32DataBus << 14));
|
||||
LPC_EMC->DYNAMICCONFIG2 = ((u32Width << 7) | (u32Size << 9) | (1UL << 12) | (u32DataBus << 14));
|
||||
|
||||
LPC_EMC->DYNAMICRASCAS0 = (3 << 0) | (3 << 8); // aem
|
||||
LPC_EMC->DYNAMICRASCAS2 = (3 << 0) | (3 << 8); // aem
|
||||
|
||||
LPC_EMC->DYNAMICREADCONFIG = EMC_COMMAND_DELAYED_STRATEGY;
|
||||
|
||||
LPC_EMC->DYNAMICRP = 1; // calculated from xls sheet
|
||||
LPC_EMC->DYNAMICRAS = 3;
|
||||
LPC_EMC->DYNAMICSREX = 5;
|
||||
LPC_EMC->DYNAMICAPR = 0;
|
||||
LPC_EMC->DYNAMICDAL = 4;
|
||||
LPC_EMC->DYNAMICWR = 1;
|
||||
LPC_EMC->DYNAMICRC = 5;
|
||||
LPC_EMC->DYNAMICRFC = 5;
|
||||
LPC_EMC->DYNAMICXSR = 5;
|
||||
LPC_EMC->DYNAMICRRD = 1;
|
||||
LPC_EMC->DYNAMICMRD = 1;
|
||||
|
||||
LPC_EMC->DYNAMICCONTROL = EMC_CE_ENABLE | EMC_CS_ENABLE | EMC_INIT(EMC_NOP);
|
||||
emc_WaitUS(100);
|
||||
|
||||
LPC_EMC->DYNAMICCONTROL = EMC_CE_ENABLE | EMC_CS_ENABLE | EMC_INIT(EMC_PRECHARGE_ALL);
|
||||
|
||||
LPC_EMC->DYNAMICREFRESH = 2;
|
||||
emc_WaitUS(100);
|
||||
|
||||
LPC_EMC->DYNAMICREFRESH = 50;
|
||||
|
||||
LPC_EMC->DYNAMICCONTROL = EMC_CE_ENABLE | EMC_CS_ENABLE | EMC_INIT(EMC_MODE);
|
||||
|
||||
if(u32DataBus == 0)
|
||||
{
|
||||
/* burst size 8 */
|
||||
*((volatile uint32_t *)(u32BaseAddr | ((3 | (3 << 4)) << (u32ColAddrBits + 1))));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* burst size 4 */
|
||||
*((volatile uint32_t *)(u32BaseAddr | ((2UL | (2UL << 4)) << (u32ColAddrBits + 2))));
|
||||
}
|
||||
|
||||
LPC_EMC->DYNAMICCONTROL = 0; // EMC_CE_ENABLE | EMC_CS_ENABLE;
|
||||
LPC_EMC->DYNAMICCONFIG0 = ((u32Width << 7) | (u32Size << 9) | (1UL << 12) | (u32DataBus << 14)) | EMC_B_ENABLE;
|
||||
LPC_EMC->DYNAMICCONFIG1 = ((u32Width << 7) | (u32Size << 9) | (1UL << 12) | (u32DataBus << 14)) | EMC_B_ENABLE;
|
||||
LPC_EMC->DYNAMICCONFIG2 = ((u32Width << 7) | (u32Size << 9) | (1UL << 12) | (u32DataBus << 14)) | EMC_B_ENABLE;
|
||||
LPC_EMC->DYNAMICCONFIG3 = ((u32Width << 7) | (u32Size << 9) | (1UL << 12) | (u32DataBus << 14)) | EMC_B_ENABLE;
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_evrt.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_evrt.c
|
||||
* @brief Contains all functions support for Event Router firmware
|
||||
* library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup EVRT
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_evrt.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup EVRT_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Initializes the EVRT peripheral.
|
||||
* @param[in] EVRTx EVRT peripheral selected, should be: LPC_EVRT
|
||||
* @return None
|
||||
*********************************************************************/
|
||||
void EVRT_Init (LPC_EVENTROUTER_Type *EVRTx)
|
||||
{
|
||||
uint8_t i=0;
|
||||
|
||||
CHECK_PARAM(PARAM_EVRTx(EVRTx));
|
||||
|
||||
// Clear all register to be default
|
||||
EVRTx->HILO = 0x0000;
|
||||
EVRTx->EDGE = 0x0000;
|
||||
EVRTx->CLR_EN = 0xFFFF;
|
||||
do
|
||||
{
|
||||
i++;
|
||||
EVRTx->CLR_STAT = 0xFFFFF;
|
||||
}while((EVRTx->STATUS != 0)&&(i<10));
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief De-initializes the EVRT peripheral registers to their
|
||||
* default reset values.
|
||||
* @param[in] EVRTx EVRT peripheral selected, should be: LPC_EVRT
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void EVRT_DeInit(LPC_EVENTROUTER_Type *EVRTx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_EVRTx(EVRTx));
|
||||
|
||||
EVRTx->CLR_EN = 0xFFFF;
|
||||
EVRTx->CLR_STAT = 0xFFFF;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Setting up the type of interrupt sources to EVRT
|
||||
* @param[in] EVRTx EVRT peripheral selected, should be: LPC_EVRT
|
||||
* @param[in] EVRT_Src EVRT source, should be:
|
||||
* - EVRT_SRC_WAKEUP0 :WAKEUP0 event
|
||||
* - EVRT_SRC_WAKEUP1 :WAKEUP1 event
|
||||
* - EVRT_SRC_WAKEUP2 :WAKEUP2 event
|
||||
* - EVRT_SRC_WAKEUP3 :WAKEUP3 event
|
||||
* - EVRT_SRC_ATIMER :Alarm timer eveny
|
||||
* - EVRT_SRC_RTC :RTC event
|
||||
* - EVRT_SRC_BOD :BOD event
|
||||
* - EVRT_SRC_WWDT :WWDT event
|
||||
* - EVRT_SRC_ETHERNET :ETHERNET event
|
||||
* - EVRT_SRC_USB0 :USB0 event
|
||||
* - EVRT_SRC_USB1 :USB1 event
|
||||
* - EVRT_SRC_CCAN :CCAN event
|
||||
* - EVRT_SRC_COMBINE_TIMER2 :Combined timer output 2 event
|
||||
* - EVRT_SRC_COMBINE_TIMER6 :Combined timer output 6 event
|
||||
* - EVRT_SRC_QEI :QEI event
|
||||
* - EVRT_SRC_COMBINE_TIMER14 :Combined timer output 14 event
|
||||
* - EVRT_SRC_RESET :RESET event
|
||||
* type Active type, should be:
|
||||
* - EVRT_SRC_ACTIVE_LOW_LEVEL :Active low level
|
||||
* - EVRT_SRC_ACTIVE_HIGH_LEVEL :Active high level
|
||||
* - EVRT_SRC_ACTIVE_FALLING_EDGE :Active falling edge
|
||||
* - EVRT_SRC_ACTIVE_RISING_EDGE :Active rising edge
|
||||
* @param[in] type EVRT source active type, should be:
|
||||
* - EVRT_SRC_ACTIVE_LOW_LEVEL :Active low level
|
||||
* - EVRT_SRC_ACTIVE_HIGH_LEVEL :Active high level
|
||||
* - EVRT_SRC_ACTIVE_FALLING_EDGE :Active falling edge
|
||||
* - EVRT_SRC_ACTIVE_RISING_EDGE :Active rising edge
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void EVRT_ConfigIntSrcActiveType(LPC_EVENTROUTER_Type *EVRTx, EVRT_SRC_ENUM EVRT_Src, EVRT_SRC_ACTIVE_TYPE type)
|
||||
{
|
||||
CHECK_PARAM(PARAM_EVRTx(EVRTx));
|
||||
CHECK_PARAM(PARAM_EVRT_SOURCE(EVRT_Src));
|
||||
CHECK_PARAM(PARAM_EVRT_SOURCE_ACTIVE_TYPE(type));
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case EVRT_SRC_ACTIVE_LOW_LEVEL:
|
||||
EVRTx->HILO &= ~(1<<(uint8_t)EVRT_Src);
|
||||
EVRTx->EDGE &= ~(1<<(uint8_t)EVRT_Src);
|
||||
break;
|
||||
case EVRT_SRC_ACTIVE_HIGH_LEVEL:
|
||||
EVRTx->HILO |= (1<<(uint8_t)EVRT_Src);
|
||||
EVRTx->EDGE &= ~(1<<(uint8_t)EVRT_Src);
|
||||
break;
|
||||
case EVRT_SRC_ACTIVE_FALLING_EDGE:
|
||||
EVRTx->HILO &= ~(1<<(uint8_t)EVRT_Src);
|
||||
EVRTx->EDGE |= (1<<(uint8_t)EVRT_Src);
|
||||
break;
|
||||
case EVRT_SRC_ACTIVE_RISING_EDGE:
|
||||
EVRTx->HILO |= (1<<(uint8_t)EVRT_Src);
|
||||
EVRTx->EDGE |= (1<<(uint8_t)EVRT_Src);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable or disable interrupt sources to EVRT
|
||||
* @param[in] EVRTx EVRT peripheral selected, should be LPC_EVRT
|
||||
* @param[in] EVRT_Src EVRT source, should be:
|
||||
* - EVRT_SRC_WAKEUP0 :WAKEUP0 event
|
||||
* - EVRT_SRC_WAKEUP1 :WAKEUP1 event
|
||||
* - EVRT_SRC_WAKEUP2 :WAKEUP2 event
|
||||
* - EVRT_SRC_WAKEUP3 :WAKEUP3 event
|
||||
* - EVRT_SRC_ATIMER :Alarm timer eveny
|
||||
* - EVRT_SRC_RTC :RTC event
|
||||
* - EVRT_SRC_BOD :BOD event
|
||||
* - EVRT_SRC_WWDT :WWDT event
|
||||
* - EVRT_SRC_ETHERNET :ETHERNET event
|
||||
* - EVRT_SRC_USB0 :USB0 event
|
||||
* - EVRT_SRC_USB1 :USB1 event
|
||||
* - EVRT_SRC_CCAN :CCAN event
|
||||
* - EVRT_SRC_COMBINE_TIMER2 :Combined timer output 2 event
|
||||
* - EVRT_SRC_COMBINE_TIMER6 :Combined timer output 6 event
|
||||
* - EVRT_SRC_QEI :QEI event
|
||||
* - EVRT_SRC_COMBINE_TIMER14 :Combined timer output 14 event
|
||||
* - EVRT_SRC_RESET :RESET event
|
||||
* @param[in] state ENABLE or DISABLE
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void EVRT_SetUpIntSrc(LPC_EVENTROUTER_Type *EVRTx, EVRT_SRC_ENUM EVRT_Src, FunctionalState state)
|
||||
{
|
||||
CHECK_PARAM(PARAM_EVRTx(EVRTx));
|
||||
CHECK_PARAM(PARAM_EVRT_SOURCE(EVRT_Src));
|
||||
|
||||
if(state == ENABLE)
|
||||
EVRTx->SET_EN = (1<<(uint8_t)EVRT_Src);
|
||||
else
|
||||
EVRTx->CLR_EN = (1<<(uint8_t)EVRT_Src);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Check if a source is sending interrupt to EVRT
|
||||
* @param[in] EVRTx EVRT peripheral selected, should be LPC_EVRT
|
||||
* @param[in] EVRT_Src EVRT source, should be:
|
||||
* - EVRT_SRC_WAKEUP0 :WAKEUP0 event
|
||||
* - EVRT_SRC_WAKEUP1 :WAKEUP1 event
|
||||
* - EVRT_SRC_WAKEUP2 :WAKEUP2 event
|
||||
* - EVRT_SRC_WAKEUP3 :WAKEUP3 event
|
||||
* - EVRT_SRC_ATIMER :Alarm timer eveny
|
||||
* - EVRT_SRC_RTC :RTC event
|
||||
* - EVRT_SRC_BOD :BOD event
|
||||
* - EVRT_SRC_WWDT :WWDT event
|
||||
* - EVRT_SRC_ETHERNET :ETHERNET event
|
||||
* - EVRT_SRC_USB0 :USB0 event
|
||||
* - EVRT_SRC_USB1 :USB1 event
|
||||
* - EVRT_SRC_CCAN :CCAN event
|
||||
* - EVRT_SRC_COMBINE_TIMER2 :Combined timer output 2 event
|
||||
* - EVRT_SRC_COMBINE_TIMER6 :Combined timer output 6 event
|
||||
* - EVRT_SRC_QEI :QEI event
|
||||
* - EVRT_SRC_COMBINE_TIMER14 :Combined timer output 14 event
|
||||
* - EVRT_SRC_RESET :RESET event
|
||||
* @return TRUE or FALSE
|
||||
**********************************************************************/
|
||||
Bool EVRT_IsSourceInterrupting(LPC_EVENTROUTER_Type *EVRTx, EVRT_SRC_ENUM EVRT_Src)
|
||||
{
|
||||
CHECK_PARAM(PARAM_EVRTx(EVRTx));
|
||||
CHECK_PARAM(PARAM_EVRT_SOURCE(EVRT_Src));
|
||||
|
||||
if(EVRTx->STATUS & (1<<(uint8_t)EVRT_Src))
|
||||
return TRUE;
|
||||
else return FALSE;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Clear pending interrupt EVRT source
|
||||
* @param[in] EVRTx EVRT peripheral selected, should be LPC_EVRT
|
||||
* @param[in] EVRT_Src EVRT source, should be:
|
||||
* - EVRT_SRC_WAKEUP0 :WAKEUP0 event
|
||||
* - EVRT_SRC_WAKEUP1 :WAKEUP1 event
|
||||
* - EVRT_SRC_WAKEUP2 :WAKEUP2 event
|
||||
* - EVRT_SRC_WAKEUP3 :WAKEUP3 event
|
||||
* - EVRT_SRC_ATIMER :Alarm timer eveny
|
||||
* - EVRT_SRC_RTC :RTC event
|
||||
* - EVRT_SRC_BOD :BOD event
|
||||
* - EVRT_SRC_WWDT :WWDT event
|
||||
* - EVRT_SRC_ETHERNET :ETHERNET event
|
||||
* - EVRT_SRC_USB0 :USB0 event
|
||||
* - EVRT_SRC_USB1 :USB1 event
|
||||
* - EVRT_SRC_CCAN :CCAN event
|
||||
* - EVRT_SRC_COMBINE_TIMER2 :Combined timer output 2 event
|
||||
* - EVRT_SRC_COMBINE_TIMER6 :Combined timer output 6 event
|
||||
* - EVRT_SRC_QEI :QEI event
|
||||
* - EVRT_SRC_COMBINE_TIMER14 :Combined timer output 14 event
|
||||
* - EVRT_SRC_RESET :RESET event
|
||||
* @return none
|
||||
**********************************************************************/
|
||||
void EVRT_ClrPendIntSrc(LPC_EVENTROUTER_Type *EVRTx, EVRT_SRC_ENUM EVRT_Src)
|
||||
{
|
||||
CHECK_PARAM(PARAM_EVRTx(EVRTx));
|
||||
CHECK_PARAM(PARAM_EVRT_SOURCE(EVRT_Src));
|
||||
|
||||
EVRTx->CLR_STAT = (1<<(uint8_t)EVRT_Src);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* --------------------------------- End Of File ------------------------------ */
|
||||
@@ -0,0 +1,571 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_gpdma.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_gpdma.c
|
||||
* @brief Contains all functions support for GPDMA firmware library
|
||||
* on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup GPDMA
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_gpdma.h"
|
||||
//#include "lpc43xx_cgu.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
#ifdef _GPDMA
|
||||
|
||||
/** GPDMA Mux definitions */
|
||||
#define DMAMUX_ADDRESS 0x4004311C
|
||||
|
||||
/* Private Functions ----------------------------------------------------------- */
|
||||
/** @
|
||||
* @{
|
||||
*/
|
||||
uint8_t DMAMUX_Config(uint32_t gpdma_peripheral_connection_number);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private Variables ---------------------------------------------------------- */
|
||||
/** @defgroup GPDMA_Private_Variables GPDMA Private Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Lookup Table of Connection Type matched with
|
||||
* Peripheral Data (FIFO) register base address
|
||||
*/
|
||||
#ifdef __ICCARM__
|
||||
volatile const void *GPDMA_LUTPerAddr[] = {
|
||||
NULL,
|
||||
(&LPC_TIMER0->MR), // MAT0.0
|
||||
(&LPC_USART0->/*RBTHDLR.*/THR), // UART0 Tx
|
||||
((uint32_t*)&LPC_TIMER0->MR + 1), // MAT0.1
|
||||
(&LPC_USART0->/*RBTHDLR.*/RBR), // UART0 Rx
|
||||
(&LPC_TIMER1->MR), // MAT1.0
|
||||
(&LPC_UART1->/*RBTHDLR.*/THR), // UART1 Tx
|
||||
((uint32_t*)&LPC_TIMER1->MR + 1), // MAT1.1
|
||||
(&LPC_UART1->/*RBTHDLR.*/RBR), // UART1 Rx
|
||||
(&LPC_TIMER2->MR), // MAT2.0
|
||||
(&LPC_USART2->/*RBTHDLR.*/THR), // UART2 Tx
|
||||
((uint32_t*)&LPC_TIMER2->MR + 1), // MAT2.1
|
||||
(&LPC_USART2->/*RBTHDLR.*/RBR), // UART2 Rx
|
||||
(&LPC_TIMER3->MR), // MAT3.0
|
||||
(&LPC_USART3->/*RBTHDLR.*/THR), // UART3 Tx
|
||||
0, // to be defined: SCT DMA request 0
|
||||
((uint32_t*)&LPC_TIMER3->MR + 1), // MAT3.1
|
||||
(&LPC_USART3->/*RBTHDLR.*/RBR), // UART3 Rx
|
||||
0, // to be defined: SCT DMA request 1
|
||||
(&LPC_SSP0->DR), // SSP0 Rx
|
||||
(&LPC_I2S0->TXFIFO), // I2S channel 0
|
||||
(&LPC_SSP0->DR), // SSP0 Tx
|
||||
(&LPC_I2S0->RXFIFO), // I2S channel 1
|
||||
(&LPC_SSP1->DR), // SSP1 Rx
|
||||
(&LPC_SSP1->DR), // SSP1 Tx
|
||||
(&LPC_ADC0->GDR), // ADC 0
|
||||
(&LPC_ADC1->GDR), // ADC 1
|
||||
(&LPC_DAC->CR) // DAC
|
||||
};
|
||||
#else
|
||||
const uint32_t GPDMA_LUTPerAddr[] = {
|
||||
((uint32_t)0), // Reserved
|
||||
((uint32_t)&LPC_TIMER0->MR[0]), // MAT0.0
|
||||
((uint32_t)&LPC_USART0->/*RBTHDLR.*/THR), // UART0 Tx
|
||||
((uint32_t)&LPC_TIMER0->MR[1]), // MAT0.1
|
||||
((uint32_t)&LPC_USART0->/*RBTHDLR.*/RBR), // UART0 Rx
|
||||
((uint32_t)&LPC_TIMER1->MR[0]), // MAT1.0
|
||||
((uint32_t)&LPC_UART1->/*RBTHDLR.*/THR), // UART1 Tx
|
||||
((uint32_t)&LPC_TIMER1->MR[1]), // MAT1.1
|
||||
((uint32_t)&LPC_UART1->/*RBTHDLR.*/RBR), // UART1 Rx
|
||||
((uint32_t)&LPC_TIMER2->MR[0]), // MAT2.0
|
||||
((uint32_t)&LPC_USART2->/*RBTHDLR.*/THR), // UART2 Tx
|
||||
((uint32_t)&LPC_TIMER2->MR[1]), // MAT2.1
|
||||
((uint32_t)&LPC_USART2->/*RBTHDLR.*/RBR), // UART2 Rx
|
||||
((uint32_t)&LPC_TIMER3->MR[0]), // MAT3.0
|
||||
((uint32_t)&LPC_USART3->/*RBTHDLR.*/THR), // UART3 Tx
|
||||
0, // to be defined: SCT DMA request 0
|
||||
((uint32_t)&LPC_TIMER3->MR[1]), // MAT3.1
|
||||
((uint32_t)&LPC_USART3->/*RBTHDLR.*/RBR), // UART3 Rx
|
||||
0, // to be defined: SCT DMA request 1
|
||||
((uint32_t)&LPC_SSP0->DR), // SSP0 Rx
|
||||
((uint32_t)&LPC_I2S0->TXFIFO), // I2S channel 0
|
||||
((uint32_t)&LPC_SSP0->DR), // SSP0 Tx
|
||||
((uint32_t)&LPC_I2S0->RXFIFO), // I2S channel 1
|
||||
((uint32_t)&LPC_SSP1->DR), // SSP1 Rx
|
||||
((uint32_t)&LPC_SSP1->DR), // SSP1 Tx
|
||||
((uint32_t)&LPC_ADC0->GDR), // ADC 0
|
||||
((uint32_t)&LPC_ADC1->GDR), // ADC 1
|
||||
((uint32_t)&LPC_DAC->CR) // DAC
|
||||
};
|
||||
#endif
|
||||
/**
|
||||
* @brief Lookup Table of GPDMA Channel Number matched with
|
||||
* GPDMA channel pointer
|
||||
*/
|
||||
const LPC_GPDMACH_TypeDef *pGPDMACh[8] = {
|
||||
LPC_GPDMACH0, // GPDMA Channel 0
|
||||
LPC_GPDMACH1, // GPDMA Channel 1
|
||||
LPC_GPDMACH2, // GPDMA Channel 2
|
||||
LPC_GPDMACH3, // GPDMA Channel 3
|
||||
LPC_GPDMACH4, // GPDMA Channel 4
|
||||
LPC_GPDMACH5, // GPDMA Channel 5
|
||||
LPC_GPDMACH6, // GPDMA Channel 6
|
||||
LPC_GPDMACH7, // GPDMA Channel 7
|
||||
};
|
||||
/**
|
||||
* @brief Optimized Peripheral Source and Destination burst size
|
||||
*/
|
||||
const uint8_t GPDMA_LUTPerBurst[] = {
|
||||
GPDMA_BSIZE_4,
|
||||
GPDMA_BSIZE_1, // MAT0.0
|
||||
GPDMA_BSIZE_1, // UART0 Tx
|
||||
GPDMA_BSIZE_1, // MAT0.1
|
||||
GPDMA_BSIZE_1, // UART0 Rx
|
||||
GPDMA_BSIZE_1, // MAT1.0
|
||||
GPDMA_BSIZE_1, // UART1 Tx
|
||||
GPDMA_BSIZE_1, // MAT1.1
|
||||
GPDMA_BSIZE_1, // UART1 Rx
|
||||
GPDMA_BSIZE_1, // MAT2.0
|
||||
GPDMA_BSIZE_1, // UART2 Tx
|
||||
GPDMA_BSIZE_1, // MAT2.1
|
||||
GPDMA_BSIZE_1, // UART2 Rx
|
||||
GPDMA_BSIZE_1, // MAT3.0
|
||||
GPDMA_BSIZE_1, // UART3 Tx
|
||||
0, // to be defined: SCT DMA request 0
|
||||
GPDMA_BSIZE_1, // MAT3.1
|
||||
GPDMA_BSIZE_1, // UART3 Rx
|
||||
0, // to be defined: SCT DMA request 1
|
||||
GPDMA_BSIZE_4, // SSP0 Rx
|
||||
GPDMA_BSIZE_32, // I2S channel 0
|
||||
GPDMA_BSIZE_4, // SSP0 Tx
|
||||
GPDMA_BSIZE_32, // I2S channel 1
|
||||
GPDMA_BSIZE_4, // SSP1 Rx
|
||||
GPDMA_BSIZE_4, // SSP1 Tx
|
||||
GPDMA_BSIZE_4, // ADC 0
|
||||
GPDMA_BSIZE_4, // ADC 1
|
||||
GPDMA_BSIZE_1, // DAC
|
||||
};
|
||||
/**
|
||||
* @brief Optimized Peripheral Source and Destination transfer width
|
||||
*/
|
||||
const uint8_t GPDMA_LUTPerWid[] = {
|
||||
GPDMA_WIDTH_WORD,
|
||||
GPDMA_WIDTH_WORD, // MAT0.0
|
||||
GPDMA_WIDTH_BYTE, // UART0 Tx
|
||||
GPDMA_WIDTH_WORD, // MAT0.1
|
||||
GPDMA_WIDTH_BYTE, // UART0 Rx
|
||||
GPDMA_WIDTH_WORD, // MAT1.0
|
||||
GPDMA_WIDTH_BYTE, // UART1 Tx
|
||||
GPDMA_WIDTH_WORD, // MAT1.1
|
||||
GPDMA_WIDTH_BYTE, // UART1 Rx
|
||||
GPDMA_WIDTH_WORD, // MAT2.0
|
||||
GPDMA_WIDTH_BYTE, // UART2 Tx
|
||||
GPDMA_WIDTH_WORD, // MAT2.1
|
||||
GPDMA_WIDTH_BYTE, // UART2 Rx
|
||||
GPDMA_WIDTH_WORD, // MAT3.0
|
||||
GPDMA_WIDTH_BYTE, // UART3 Tx
|
||||
0, // to be defined: SCT DMA request 0
|
||||
GPDMA_WIDTH_WORD, // MAT3.1
|
||||
GPDMA_WIDTH_BYTE, // UART3 Rx
|
||||
0, // to be defined: SCT DMA request 1
|
||||
GPDMA_WIDTH_BYTE, // SSP0 Rx
|
||||
GPDMA_WIDTH_WORD, // I2S channel 0
|
||||
GPDMA_WIDTH_BYTE, // SSP0 Tx
|
||||
GPDMA_WIDTH_WORD, // I2S channel 1
|
||||
GPDMA_WIDTH_BYTE, // SSP1 Rx
|
||||
GPDMA_WIDTH_BYTE, // SSP1 Tx
|
||||
GPDMA_WIDTH_WORD, // ADC 0
|
||||
GPDMA_WIDTH_WORD, // ADC 1
|
||||
GPDMA_WIDTH_WORD, // DAC
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private Functions ----------------------------------------------------------- */
|
||||
/** @
|
||||
* @{
|
||||
*/
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Control which set of peripherals is connected to the
|
||||
* DMA controller
|
||||
* @param[in] gpdma_peripheral_connection_number GPDMA peripheral
|
||||
* connection number, should be:
|
||||
* - GPDMA_CONN_RESERVED
|
||||
* - GPDMA_CONN_MAT0_0 :Timer 0, match channel 0
|
||||
* - GPDMA_CONN_MAT0_1 :Timer 0, match channel 1
|
||||
* - GPDMA_CONN_MAT1_0 :Timer 1, match channel 0
|
||||
* - GPDMA_CONN_MAT1_1 :Timer 1, match channel 1
|
||||
* - GPDMA_CONN_MAT2_0 :Timer 2, match channel 0
|
||||
* - GPDMA_CONN_MAT2_1 :Timer 2, match channel 1
|
||||
* - GPDMA_CONN_MAT3_0 :Timer 3, match channel 0
|
||||
* - GPDMA_CONN_MAT3_1 :Timer 3, match channel 1
|
||||
* - GPDMA_CONN_UART0_Tx :USART 0 transmit
|
||||
* - GPDMA_CONN_UART0_Rx :USART 0 receive
|
||||
* - GPDMA_CONN_UART1_Tx :USART 1 transmit
|
||||
* - GPDMA_CONN_UART1_Rx :USART 1 receive
|
||||
* - GPDMA_CONN_UART2_Tx :USART 2 transmit
|
||||
* - GPDMA_CONN_UART2_Rx :USART 2 receive
|
||||
* - GPDMA_CONN_UART3_Tx :USART 3 transmit
|
||||
* - GPDMA_CONN_UART3_Rx :USART 3 receive
|
||||
* - GPDMA_CONN_SCT_0 :SCT output 0
|
||||
* - GPDMA_CONN_SCT_1 :SCT output 1
|
||||
* - GPDMA_CONN_I2S_Channel_0 :I2S channel 0
|
||||
* - GPDMA_CONN_I2S_Channel_1 :I2S channel 1
|
||||
* - GPDMA_CONN_SSP0_Tx :SSP0 transmit
|
||||
* - GPDMA_CONN_SSP0_Rx :SSP0 receive
|
||||
* - GPDMA_CONN_SSP1_Tx :SSP1 transmit
|
||||
* - GPDMA_CONN_SSP1_Rx :SSP1 receive
|
||||
* - GPDMA_CONN_ADC_0 :ADC0
|
||||
* - GPDMA_CONN_ADC_1 :ADC1
|
||||
* - GPDMA_CONN_DAC :DAC
|
||||
* @return channel number, could be in range: 0..16
|
||||
*********************************************************************/
|
||||
uint8_t DMAMUX_Config(uint32_t gpdma_peripheral_connection_number)
|
||||
{
|
||||
uint32_t *dmamux_reg = (uint32_t*)DMAMUX_ADDRESS;
|
||||
uint8_t function, channel;
|
||||
|
||||
switch(gpdma_peripheral_connection_number)
|
||||
{
|
||||
case GPDMA_CONN_RESERVED: function = 0; channel = 0; break;
|
||||
case GPDMA_CONN_MAT0_0: function = 0; channel = 1; break;
|
||||
case GPDMA_CONN_UART0_Tx: function = 1; channel = 1; break;
|
||||
case GPDMA_CONN_MAT0_1: function = 0; channel = 2; break;
|
||||
case GPDMA_CONN_UART0_Rx: function = 1; channel = 2; break;
|
||||
case GPDMA_CONN_MAT1_0: function = 0; channel = 3; break;
|
||||
case GPDMA_CONN_UART1_Tx: function = 1; channel = 3; break;
|
||||
case GPDMA_CONN_MAT1_1: function = 0; channel = 4; break;
|
||||
case GPDMA_CONN_UART1_Rx: function = 1; channel = 4; break;
|
||||
case GPDMA_CONN_MAT2_0: function = 0; channel = 5; break;
|
||||
case GPDMA_CONN_UART2_Tx: function = 1; channel = 5; break;
|
||||
case GPDMA_CONN_MAT2_1: function = 0; channel = 6; break;
|
||||
case GPDMA_CONN_UART2_Rx: function = 1; channel = 6; break;
|
||||
case GPDMA_CONN_MAT3_0: function = 0; channel = 7; break;
|
||||
case GPDMA_CONN_UART3_Tx: function = 1; channel = 7; break;
|
||||
case GPDMA_CONN_SCT_0: function = 2; channel = 7; break;
|
||||
case GPDMA_CONN_MAT3_1: function = 0; channel = 8; break;
|
||||
case GPDMA_CONN_UART3_Rx: function = 1; channel = 8; break;
|
||||
case GPDMA_CONN_SCT_1: function = 2; channel = 8; break;
|
||||
case GPDMA_CONN_SSP0_Rx: function = 0; channel = 9; break;
|
||||
case GPDMA_CONN_I2S_Channel_0:function = 1; channel = 9; break;
|
||||
case GPDMA_CONN_SSP0_Tx: function = 0; channel = 10; break;
|
||||
case GPDMA_CONN_I2S_Channel_1:function = 1; channel = 10; break;
|
||||
case GPDMA_CONN_SSP1_Rx: function = 0; channel = 11; break;
|
||||
case GPDMA_CONN_SSP1_Tx: function = 0; channel = 12; break;
|
||||
case GPDMA_CONN_ADC_0: function = 0; channel = 13; break;
|
||||
case GPDMA_CONN_ADC_1: function = 0; channel = 14; break;
|
||||
case GPDMA_CONN_DAC: function = 0; channel = 15; break;
|
||||
default: function = 3; channel = 15; break;
|
||||
}
|
||||
//Set select function to dmamux register
|
||||
*dmamux_reg &= ~(0x03<<(2*channel));
|
||||
*dmamux_reg |= (function<<(2*channel));
|
||||
|
||||
return channel;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup GPDMA_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Initialize GPDMA controller
|
||||
* @param[in] None
|
||||
* @return None
|
||||
*********************************************************************/
|
||||
void GPDMA_Init(void)
|
||||
{
|
||||
/* to be defined Enable GPDMA clock */
|
||||
// enabled default on reset
|
||||
|
||||
// Reset all channel configuration register
|
||||
LPC_GPDMACH0->CConfig = 0;
|
||||
LPC_GPDMACH1->CConfig = 0;
|
||||
LPC_GPDMACH2->CConfig = 0;
|
||||
LPC_GPDMACH3->CConfig = 0;
|
||||
LPC_GPDMACH4->CConfig = 0;
|
||||
LPC_GPDMACH5->CConfig = 0;
|
||||
LPC_GPDMACH6->CConfig = 0;
|
||||
LPC_GPDMACH7->CConfig = 0;
|
||||
|
||||
/* Clear all DMA interrupt and error flag */
|
||||
LPC_GPDMA->INTTCCLEAR = 0xFF;
|
||||
LPC_GPDMA->INTERRCLR = 0xFF;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Setup GPDMA channel peripheral according to the specified
|
||||
* parameters in the GPDMAChannelConfig.
|
||||
* @param[in] GPDMAChannelConfig Pointer to a GPDMA_CH_CFG_Type structure
|
||||
* that contains the configuration information for the specified
|
||||
* GPDMA channel peripheral.
|
||||
* @return Setup status, could be:
|
||||
* - ERROR :if selected channel is enabled before
|
||||
* - SUCCESS :if channel is configured successfully
|
||||
*********************************************************************/
|
||||
Status GPDMA_Setup(GPDMA_Channel_CFG_Type *GPDMAChannelConfig)
|
||||
{
|
||||
LPC_GPDMACH_TypeDef *pDMAch;
|
||||
uint8_t SrcPeripheral=0, DestPeripheral=0;
|
||||
|
||||
if (LPC_GPDMA->ENBLDCHNS & (GPDMA_DMACEnbldChns_Ch(GPDMAChannelConfig->ChannelNum))) {
|
||||
// This channel is enabled, return ERROR, need to release this channel first
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
// Get Channel pointer
|
||||
pDMAch = (LPC_GPDMACH_TypeDef *) pGPDMACh[GPDMAChannelConfig->ChannelNum];
|
||||
|
||||
// Reset the Interrupt status
|
||||
LPC_GPDMA->INTTCCLEAR = GPDMA_DMACIntTCClear_Ch(GPDMAChannelConfig->ChannelNum);
|
||||
LPC_GPDMA->INTERRCLR = GPDMA_DMACIntErrClr_Ch(GPDMAChannelConfig->ChannelNum);
|
||||
|
||||
// Clear DMA configure
|
||||
pDMAch->CControl = 0x00;
|
||||
pDMAch->CConfig = 0x00;
|
||||
|
||||
/* Assign Linker List Item value */
|
||||
pDMAch->CLLI = GPDMAChannelConfig->DMALLI;
|
||||
|
||||
/* Set value to Channel Control Registers */
|
||||
switch (GPDMAChannelConfig->TransferType)
|
||||
{
|
||||
// Memory to memory
|
||||
case GPDMA_TRANSFERTYPE_M2M_CONTROLLER_DMA:
|
||||
// Assign physical source and destination address
|
||||
pDMAch->CSrcAddr = GPDMAChannelConfig->SrcMemAddr;
|
||||
pDMAch->CDestAddr = GPDMAChannelConfig->DstMemAddr;
|
||||
pDMAch->CControl
|
||||
= GPDMA_DMACCxControl_TransferSize(GPDMAChannelConfig->TransferSize) \
|
||||
| GPDMA_DMACCxControl_SBSize(GPDMA_BSIZE_32) \
|
||||
| GPDMA_DMACCxControl_DBSize(GPDMA_BSIZE_32) \
|
||||
| GPDMA_DMACCxControl_SWidth(GPDMAChannelConfig->TransferWidth) \
|
||||
| GPDMA_DMACCxControl_DWidth(GPDMAChannelConfig->TransferWidth) \
|
||||
| GPDMA_DMACCxControl_SI \
|
||||
| GPDMA_DMACCxControl_DI \
|
||||
| GPDMA_DMACCxControl_I;
|
||||
break;
|
||||
// Memory to peripheral
|
||||
case GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA:
|
||||
// Assign physical source
|
||||
pDMAch->CSrcAddr = GPDMAChannelConfig->SrcMemAddr;
|
||||
// Assign peripheral destination address
|
||||
pDMAch->CDestAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->DstConn];
|
||||
pDMAch->CControl
|
||||
= GPDMA_DMACCxControl_TransferSize((uint32_t)GPDMAChannelConfig->TransferSize) \
|
||||
| GPDMA_DMACCxControl_SBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->DstConn]) \
|
||||
| GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->DstConn]) \
|
||||
| GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->DstConn]) \
|
||||
| GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->DstConn]) \
|
||||
| GPDMA_DMACCxControl_DestTransUseAHBMaster1 \
|
||||
| GPDMA_DMACCxControl_SI \
|
||||
| GPDMA_DMACCxControl_I;
|
||||
DestPeripheral = DMAMUX_Config(GPDMAChannelConfig->DstConn);
|
||||
break;
|
||||
// Peripheral to memory
|
||||
case GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA:
|
||||
// Assign peripheral source address
|
||||
pDMAch->CSrcAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->SrcConn];
|
||||
// Assign memory destination address
|
||||
pDMAch->CDestAddr = GPDMAChannelConfig->DstMemAddr;
|
||||
pDMAch->CControl
|
||||
= GPDMA_DMACCxControl_TransferSize((uint32_t)GPDMAChannelConfig->TransferSize) \
|
||||
| GPDMA_DMACCxControl_SBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->SrcConn]) \
|
||||
| GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->SrcConn]) \
|
||||
| GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->SrcConn]) \
|
||||
| GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->SrcConn]) \
|
||||
| GPDMA_DMACCxControl_SrcTransUseAHBMaster1 \
|
||||
| GPDMA_DMACCxControl_DI \
|
||||
| GPDMA_DMACCxControl_I;
|
||||
SrcPeripheral = DMAMUX_Config(GPDMAChannelConfig->SrcConn);
|
||||
break;
|
||||
// Peripheral to peripheral
|
||||
case GPDMA_TRANSFERTYPE_P2P_CONTROLLER_DMA:
|
||||
// Assign peripheral source address
|
||||
pDMAch->CSrcAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->SrcConn];
|
||||
// Assign peripheral destination address
|
||||
pDMAch->CDestAddr = (uint32_t)GPDMA_LUTPerAddr[GPDMAChannelConfig->DstConn];
|
||||
pDMAch->CControl
|
||||
= GPDMA_DMACCxControl_TransferSize((uint32_t)GPDMAChannelConfig->TransferSize) \
|
||||
| GPDMA_DMACCxControl_SBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->SrcConn]) \
|
||||
| GPDMA_DMACCxControl_DBSize((uint32_t)GPDMA_LUTPerBurst[GPDMAChannelConfig->DstConn]) \
|
||||
| GPDMA_DMACCxControl_SWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->SrcConn]) \
|
||||
| GPDMA_DMACCxControl_DWidth((uint32_t)GPDMA_LUTPerWid[GPDMAChannelConfig->DstConn]) \
|
||||
| GPDMA_DMACCxControl_SrcTransUseAHBMaster1 \
|
||||
| GPDMA_DMACCxControl_DestTransUseAHBMaster1 \
|
||||
| GPDMA_DMACCxControl_I;
|
||||
SrcPeripheral = DMAMUX_Config(GPDMAChannelConfig->SrcConn);
|
||||
DestPeripheral = DMAMUX_Config(GPDMAChannelConfig->DstConn);
|
||||
break;
|
||||
|
||||
case GPDMA_TRANSFERTYPE_P2P_CONTROLLER_DestPERIPHERAL:
|
||||
case GPDMA_TRANSFERTYPE_M2P_CONTROLLER_PERIPHERAL:
|
||||
case GPDMA_TRANSFERTYPE_P2M_CONTROLLER_PERIPHERAL:
|
||||
case GPDMA_TRANSFERTYPE_P2P_CONTROLLER_SrcPERIPHERAL:
|
||||
//to be defined
|
||||
// Do not support any more transfer type, return ERROR
|
||||
default:
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Enable DMA channels, little endian */
|
||||
LPC_GPDMA->CONFIG = GPDMA_DMACConfig_E;
|
||||
while (!(LPC_GPDMA->CONFIG & GPDMA_DMACConfig_E));
|
||||
|
||||
// Configure DMA Channel, enable Error Counter and Terminate counter
|
||||
pDMAch->CConfig = GPDMA_DMACCxConfig_IE | GPDMA_DMACCxConfig_ITC /*| GPDMA_DMACCxConfig_E*/ \
|
||||
| GPDMA_DMACCxConfig_TransferType((uint32_t)GPDMAChannelConfig->TransferType) \
|
||||
| GPDMA_DMACCxConfig_SrcPeripheral(SrcPeripheral) \
|
||||
| GPDMA_DMACCxConfig_DestPeripheral(DestPeripheral);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable/Disable DMA channel
|
||||
* @param[in] channelNum GPDMA channel, should be in range from 0 to 15
|
||||
* @param[in] NewState New State of this command, should be:
|
||||
* - ENABLE.
|
||||
* - DISABLE.
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void GPDMA_ChannelCmd(uint8_t channelNum, FunctionalState NewState)
|
||||
{
|
||||
LPC_GPDMACH_TypeDef *pDMAch;
|
||||
|
||||
// Get Channel pointer
|
||||
pDMAch = (LPC_GPDMACH_TypeDef *) pGPDMACh[channelNum];
|
||||
|
||||
if (NewState == ENABLE) {
|
||||
pDMAch->CConfig |= GPDMA_DMACCxConfig_E;
|
||||
} else {
|
||||
pDMAch->CConfig &= ~GPDMA_DMACCxConfig_E;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Check if corresponding channel does have an active interrupt
|
||||
* request or not
|
||||
* @param[in] type type of status, should be:
|
||||
* - GPDMA_STAT_INT :GPDMA Interrupt Status
|
||||
* - GPDMA_STAT_INTTC :GPDMA Interrupt Terminal Count Request Status
|
||||
* - GPDMA_STAT_INTERR :GPDMA Interrupt Error Status
|
||||
* - GPDMA_STAT_RAWINTTC :GPDMA Raw Interrupt Terminal Count Status
|
||||
* - GPDMA_STAT_RAWINTERR :GPDMA Raw Error Interrupt Status
|
||||
* - GPDMA_STAT_ENABLED_CH :GPDMA Enabled Channel Status
|
||||
* @param[in] channel GPDMA channel, should be in range from 0 to 7
|
||||
* @return IntStatus status of DMA channel interrupt after masking
|
||||
* Should be:
|
||||
* - SET :the corresponding channel has no active interrupt request
|
||||
* - RESET :the corresponding channel does have an active interrupt request
|
||||
**********************************************************************/
|
||||
IntStatus GPDMA_IntGetStatus(GPDMA_Status_Type type, uint8_t channel)
|
||||
{
|
||||
CHECK_PARAM(PARAM_GPDMA_STAT(type));
|
||||
CHECK_PARAM(PARAM_GPDMA_CHANNEL(channel));
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case GPDMA_STAT_INT: //check status of DMA channel interrupts
|
||||
if (LPC_GPDMA->INTSTAT & (GPDMA_DMACIntStat_Ch(channel)))
|
||||
return SET;
|
||||
return RESET;
|
||||
case GPDMA_STAT_INTTC: // check terminal count interrupt request status for DMA
|
||||
if (LPC_GPDMA->INTTCSTAT & GPDMA_DMACIntTCStat_Ch(channel))
|
||||
return SET;
|
||||
return RESET;
|
||||
case GPDMA_STAT_INTERR: //check interrupt status for DMA channels
|
||||
if (LPC_GPDMA->INTERRSTAT & GPDMA_DMACIntTCClear_Ch(channel))
|
||||
return SET;
|
||||
return RESET;
|
||||
case GPDMA_STAT_RAWINTTC: //check status of the terminal count interrupt for DMA channels
|
||||
if (LPC_GPDMA->RAWINTERRSTAT & GPDMA_DMACRawIntTCStat_Ch(channel))
|
||||
return SET;
|
||||
return RESET;
|
||||
case GPDMA_STAT_RAWINTERR: //check status of the error interrupt for DMA channels
|
||||
if (LPC_GPDMA->RAWINTTCSTAT & GPDMA_DMACRawIntErrStat_Ch(channel))
|
||||
return SET;
|
||||
return RESET;
|
||||
default: //check enable status for DMA channels
|
||||
if (LPC_GPDMA->ENBLDCHNS & GPDMA_DMACEnbldChns_Ch(channel))
|
||||
return SET;
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Clear one or more interrupt requests on DMA channels
|
||||
* @param[in] type type of interrupt request, should be:
|
||||
* - GPDMA_STATCLR_INTTC :GPDMA Interrupt Terminal Count Request Clear
|
||||
* - GPDMA_STATCLR_INTERR :GPDMA Interrupt Error Clear
|
||||
* @param[in] channel GPDMA channel, should be in range from 0 to 15
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void GPDMA_ClearIntPending(GPDMA_StateClear_Type type, uint8_t channel)
|
||||
{
|
||||
CHECK_PARAM(PARAM_GPDMA_STATCLR(type));
|
||||
CHECK_PARAM(PARAM_GPDMA_CHANNEL(channel));
|
||||
|
||||
if (type == GPDMA_STATCLR_INTTC) // clears the terminal count interrupt request on DMA channel
|
||||
LPC_GPDMA->INTTCCLEAR = GPDMA_DMACIntTCClear_Ch(channel);
|
||||
else // clear the error interrupt request
|
||||
LPC_GPDMA->INTERRCLR = GPDMA_DMACIntErrClr_Ch(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _GPDMA */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* --------------------------------- End Of File ------------------------------ */
|
||||
@@ -0,0 +1,325 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_gpio.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_gpio.c
|
||||
* @brief Contains all functions support for GPIO firmware library
|
||||
* on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup GPIO
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_gpio.h"
|
||||
#include "lpc_types.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
|
||||
#ifdef _GPIO
|
||||
|
||||
/* Private Functions ---------------------------------------------------------- */
|
||||
|
||||
/* End of Private Functions --------------------------------------------------- */
|
||||
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup GPIO_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/* GPIO ------------------------------------------------------------------------------ */
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set Direction for GPIO port.
|
||||
* @param[in] portNum Port Number value, should be in range from 0 to 4
|
||||
* @param[in] bitValue Value that contains all bits to set direction,
|
||||
* in range from 0 to 0xFFFFFFFF.
|
||||
* example: value 0x5 to set direction for bit 0 and bit 1.
|
||||
* @param[in] dir Direction value, should be:
|
||||
* - 0: Input.
|
||||
* - 1: Output.
|
||||
* @return None
|
||||
*
|
||||
* Note:
|
||||
* All remaining bits that are not activated in bitValue (value '0')
|
||||
* will not be effected by this function.
|
||||
**********************************************************************/
|
||||
void GPIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir)
|
||||
{
|
||||
if (dir)
|
||||
{
|
||||
LPC_GPIO_PORT->DIR[portNum] |= bitValue;
|
||||
} else
|
||||
{
|
||||
LPC_GPIO_PORT->DIR[portNum] &= ~bitValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set Value for bits that have output direction on GPIO port.
|
||||
* @param[in] portNum Port number value, should be in range from 0 to 4
|
||||
* @param[in] bitValue Value that contains all bits on GPIO to set, should
|
||||
* be in range from 0 to 0xFFFFFFFF.
|
||||
* example: value 0x5 to set bit 0 and bit 1.
|
||||
* @return None
|
||||
*
|
||||
* Note:
|
||||
* - For all bits that has been set as input direction, this function will
|
||||
* not effect.
|
||||
* - For all remaining bits that are not activated in bitValue (value '0')
|
||||
* will not be effected by this function.
|
||||
**********************************************************************/
|
||||
void GPIO_SetValue(uint8_t portNum, uint32_t bitValue)
|
||||
{
|
||||
LPC_GPIO_PORT->SET[portNum] = bitValue;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Clear Value for bits that have output direction on GPIO port.
|
||||
* @param[in] portNum Port number value, should be in range from 0 to 4
|
||||
* @param[in] bitValue Value that contains all bits on GPIO to clear, should
|
||||
* be in range from 0 to 0xFFFFFFFF.
|
||||
* example: value 0x5 to clear bit 0 and bit 1.
|
||||
* @return None
|
||||
*
|
||||
* Note:
|
||||
* - For all bits that has been set as input direction, this function will
|
||||
* not effect.
|
||||
* - For all remaining bits that are not activated in bitValue (value '0')
|
||||
* will not be effected by this function.
|
||||
**********************************************************************/
|
||||
void GPIO_ClearValue(uint8_t portNum, uint32_t bitValue)
|
||||
{
|
||||
LPC_GPIO_PORT->CLR[portNum] = bitValue;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Read Current state on port pin that have input direction of GPIO
|
||||
* @param[in] portNum Port number to read value, in range from 0 to 4
|
||||
* @return Current value of GPIO port.
|
||||
*
|
||||
* Note: Return value contain state of each port pin (bit) on that GPIO regardless
|
||||
* its direction is input or output.
|
||||
**********************************************************************/
|
||||
uint32_t GPIO_ReadValue(uint8_t portNum)
|
||||
{
|
||||
return LPC_GPIO_PORT->PIN[portNum];
|
||||
}
|
||||
|
||||
|
||||
#ifdef GPIO_INT
|
||||
/*********************************************************************//**
|
||||
* @brief Enable GPIO interrupt (just used for P0.0-P0.30, P2.0-P2.13)
|
||||
* @param[in] portNum Port number to read value, should be: 0 or 2
|
||||
* @param[in] bitValue Value that contains all bits on GPIO to enable,
|
||||
* should be in range from 0 to 0xFFFFFFFF.
|
||||
* @param[in] edgeState state of edge, should be:
|
||||
* - 0: Rising edge
|
||||
* - 1: Falling edge
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void GPIO_IntCmd(uint8_t portNum, uint32_t bitValue, uint8_t edgeState)
|
||||
{
|
||||
if((portNum == 0)&&(edgeState == 0))
|
||||
LPC_GPIOINT->IO0IntEnR = bitValue;
|
||||
else if ((portNum == 2)&&(edgeState == 0))
|
||||
LPC_GPIOINT->IO2IntEnR = bitValue;
|
||||
else if ((portNum == 0)&&(edgeState == 1))
|
||||
LPC_GPIOINT->IO0IntEnF = bitValue;
|
||||
else if ((portNum == 2)&&(edgeState == 1))
|
||||
LPC_GPIOINT->IO2IntEnF = bitValue;
|
||||
else
|
||||
//Error
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get GPIO Interrupt Status (just used for P0.0-P0.30, P2.0-P2.13)
|
||||
* @param[in] portNum Port number to read value, should be: 0 or 2
|
||||
* @param[in] pinNum Pin number, should be: 0..30(with port 0) and 0..13
|
||||
* (with port 2)
|
||||
* @param[in] edgeState state of edge, should be:
|
||||
* - 0 :Rising edge
|
||||
* - 1 :Falling edge
|
||||
* @return Function status, could be:
|
||||
* - ENABLE :Interrupt has been generated due to a rising edge on P0.0
|
||||
* - DISABLE :A rising edge has not been detected on P0.0
|
||||
**********************************************************************/
|
||||
FunctionalState GPIO_GetIntStatus(uint8_t portNum, uint32_t pinNum, uint8_t edgeState)
|
||||
{
|
||||
if((portNum == 0) && (edgeState == 0))//Rising Edge
|
||||
return (((LPC_GPIOINT->IO0IntStatR)>>pinNum)& 0x1);
|
||||
else if ((portNum == 2) && (edgeState == 0))
|
||||
return (((LPC_GPIOINT->IO2IntStatR)>>pinNum)& 0x1);
|
||||
else if ((portNum == 0) && (edgeState == 1))//Falling Edge
|
||||
return (((LPC_GPIOINT->IO0IntStatF)>>pinNum)& 0x1);
|
||||
else if ((portNum == 2) && (edgeState == 1))
|
||||
return (((LPC_GPIOINT->IO2IntStatF)>>pinNum)& 0x1);
|
||||
else
|
||||
//Error
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Clear GPIO interrupt (just used for P0.0-P0.30, P2.0-P2.13)
|
||||
* @param[in] portNum Port number to read value, should be: 0 or 2
|
||||
* @param[in] bitValue Value that contains all bits on GPIO to enable,
|
||||
* should be in range from 0 to 0xFFFFFFFF.
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void GPIO_ClearInt(uint8_t portNum, uint32_t bitValue)
|
||||
{
|
||||
if(portNum == 0)
|
||||
LPC_GPIOINT->IO0IntClr = bitValue;
|
||||
else if (portNum == 2)
|
||||
LPC_GPIOINT->IO2IntClr = bitValue;
|
||||
else
|
||||
//Invalid portNum
|
||||
while(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* FIO word accessible ----------------------------------------------------------------- */
|
||||
/* Stub function for FIO (word-accessible) style */
|
||||
|
||||
/**
|
||||
* @brief The same with GPIO_SetDir()
|
||||
*/
|
||||
void FIO_SetDir(uint8_t portNum, uint32_t bitValue, uint8_t dir)
|
||||
{
|
||||
GPIO_SetDir(portNum, bitValue, dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The same with GPIO_SetValue()
|
||||
*/
|
||||
void FIO_SetValue(uint8_t portNum, uint32_t bitValue)
|
||||
{
|
||||
GPIO_SetValue(portNum, bitValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The same with GPIO_ClearValue()
|
||||
*/
|
||||
void FIO_ClearValue(uint8_t portNum, uint32_t bitValue)
|
||||
{
|
||||
GPIO_ClearValue(portNum, bitValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The same with GPIO_ReadValue()
|
||||
*/
|
||||
uint32_t FIO_ReadValue(uint8_t portNum)
|
||||
{
|
||||
return (GPIO_ReadValue(portNum));
|
||||
}
|
||||
|
||||
|
||||
#ifdef GPIO_INT
|
||||
/**
|
||||
* @brief The same with GPIO_IntCmd()
|
||||
*/
|
||||
void FIO_IntCmd(uint8_t portNum, uint32_t bitValue, uint8_t edgeState)
|
||||
{
|
||||
GPIO_IntCmd(portNum, bitValue, edgeState);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The same with GPIO_GetIntStatus()
|
||||
*/
|
||||
FunctionalState FIO_GetIntStatus(uint8_t portNum, uint32_t pinNum, uint8_t edgeState)
|
||||
{
|
||||
return (GPIO_GetIntStatus(portNum, pinNum, edgeState));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The same with GPIO_ClearInt()
|
||||
*/
|
||||
void FIO_ClearInt(uint8_t portNum, uint32_t bitValue)
|
||||
{
|
||||
GPIO_ClearInt(portNum, bitValue);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set mask value for bits in FIO port
|
||||
* @param[in] portNum Port number, in range from 0 to 4
|
||||
* @param[in] bitValue Value that contains all bits in to set, should be
|
||||
* in range from 0 to 0xFFFFFFFF.
|
||||
* @param[in] maskValue Mask value contains state value for each bit:
|
||||
* - 0 :not mask.
|
||||
* - 1 :mask.
|
||||
* @return None
|
||||
*
|
||||
* Note:
|
||||
* - All remaining bits that are not activated in bitValue (value '0')
|
||||
* will not be effected by this function.
|
||||
* - After executing this function, in mask register, value '0' on each bit
|
||||
* enables an access to the corresponding physical pin via a read or write access,
|
||||
* while value '1' on bit (masked) that corresponding pin will not be changed
|
||||
* with write access and if read, will not be reflected in the updated pin.
|
||||
**********************************************************************/
|
||||
void FIO_SetMask(uint8_t portNum, uint32_t bitValue, uint8_t maskValue)
|
||||
{
|
||||
if (maskValue)
|
||||
{
|
||||
LPC_GPIO_PORT->MASK[portNum] |= bitValue;
|
||||
} else
|
||||
{
|
||||
LPC_GPIO_PORT->MASK[portNum] &= ~bitValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _GPIO */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,668 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_i2s.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_i2s.c
|
||||
* @brief Contains all functions support for I2S firmware library
|
||||
* on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup I2S
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_i2s.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
|
||||
#ifdef _I2S
|
||||
|
||||
/* Private Functions ---------------------------------------------------------- */
|
||||
|
||||
static uint8_t i2s_GetWordWidth(LPC_I2Sn_Type *I2Sx, uint8_t TRMode);
|
||||
static uint8_t i2s_GetChannel(LPC_I2Sn_Type *I2Sx, uint8_t TRMode);
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Get I2S wordwidth value
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] TRMode is the I2S mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @return The wordwidth value, should be: 8,16 or 32
|
||||
*********************************************************************/
|
||||
static uint8_t i2s_GetWordWidth(LPC_I2Sn_Type *I2Sx, uint8_t TRMode) {
|
||||
uint8_t value;
|
||||
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
|
||||
|
||||
if (TRMode == I2S_TX_MODE) {
|
||||
value = (I2Sx->DAO) & 0x03; /* get wordwidth bit */
|
||||
} else {
|
||||
value = (I2Sx->DAI) & 0x03; /* get wordwidth bit */
|
||||
}
|
||||
switch (value) {
|
||||
case I2S_WORDWIDTH_8:
|
||||
return 8;
|
||||
case I2S_WORDWIDTH_16:
|
||||
return 16;
|
||||
default:
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Get I2S channel value
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] TRMode is the I2S mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @return The channel value, should be: 1(mono) or 2(stereo)
|
||||
*********************************************************************/
|
||||
static uint8_t i2s_GetChannel(LPC_I2Sn_Type *I2Sx, uint8_t TRMode) {
|
||||
uint8_t value;
|
||||
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
|
||||
|
||||
if (TRMode == I2S_TX_MODE) {
|
||||
value = (I2Sx->DAO) & 0x04; /* get bit[2] */
|
||||
} else {
|
||||
value = (I2Sx->DAI) & 0x04; /* get bit[2] */
|
||||
}
|
||||
value >>= 2;
|
||||
if(value == I2S_MONO) return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* End of Private Functions --------------------------------------------------- */
|
||||
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup I2S_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Initialize I2S
|
||||
* - Turn on power and clock
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void I2S_Init(LPC_I2Sn_Type *I2Sx) {
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
|
||||
// Turn on power and clock
|
||||
//CGU_ConfigPPWR(CGU_PCONP_PCI2S, ENABLE);
|
||||
I2Sx->DAI = I2Sx->DAO = 0x00;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Configuration I2S, setting:
|
||||
* - master/slave mode
|
||||
* - wordwidth value
|
||||
* - channel mode
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] TRMode transmit/receive mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @param[in] ConfigStruct pointer to I2S_CFG_Type structure
|
||||
* which will be initialized.
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void I2S_Config(LPC_I2Sn_Type *I2Sx, uint8_t TRMode, I2S_CFG_Type* ConfigStruct)
|
||||
{
|
||||
uint32_t bps, config;
|
||||
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
|
||||
CHECK_PARAM(PARAM_I2S_WORDWIDTH(ConfigStruct->wordwidth));
|
||||
CHECK_PARAM(PARAM_I2S_CHANNEL(ConfigStruct->mono));
|
||||
CHECK_PARAM(PARAM_I2S_STOP(ConfigStruct->stop));
|
||||
CHECK_PARAM(PARAM_I2S_RESET(ConfigStruct->reset));
|
||||
CHECK_PARAM(PARAM_I2S_WS_SEL(ConfigStruct->ws_sel));
|
||||
CHECK_PARAM(PARAM_I2S_MUTE(ConfigStruct->mute));
|
||||
|
||||
/* Setup clock */
|
||||
bps = (ConfigStruct->wordwidth +1)*8;
|
||||
|
||||
/* Calculate audio config */
|
||||
config = (bps - 1)<<6 | (ConfigStruct->ws_sel)<<5 | (ConfigStruct->reset)<<4 |
|
||||
(ConfigStruct->stop)<<3 | (ConfigStruct->mono)<<2 | (ConfigStruct->wordwidth);
|
||||
|
||||
if(TRMode == I2S_RX_MODE){
|
||||
I2Sx->DAI = config;
|
||||
}else{
|
||||
I2Sx->DAO = config;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief DeInitial both I2S transmit or receive
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void I2S_DeInit(LPC_I2Sn_Type *I2Sx) {
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
|
||||
// Turn off power and clock
|
||||
//CGU_ConfigPPWR(CGU_PCONP_PCI2S, DISABLE);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Get I2S Buffer Level
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] TRMode Transmit/receive mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @return current level of Transmit/Receive Buffer
|
||||
*********************************************************************/
|
||||
uint8_t I2S_GetLevel(LPC_I2Sn_Type *I2Sx, uint8_t TRMode)
|
||||
{
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
|
||||
|
||||
if(TRMode == I2S_TX_MODE)
|
||||
{
|
||||
return ((I2Sx->STATE >> 16) & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((I2Sx->STATE >> 8) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief I2S Start: clear all STOP,RESET and MUTE bit, ready to operate
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void I2S_Start(LPC_I2Sn_Type *I2Sx)
|
||||
{
|
||||
//Clear STOP,RESET and MUTE bit
|
||||
I2Sx->DAO &= ~I2S_DAI_RESET;
|
||||
I2Sx->DAI &= ~I2S_DAI_RESET;
|
||||
I2Sx->DAO &= ~I2S_DAI_STOP;
|
||||
I2Sx->DAI &= ~I2S_DAI_STOP;
|
||||
I2Sx->DAO &= ~I2S_DAI_MUTE;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief I2S Send data
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] BufferData pointer to uint32_t is the data will be send
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void I2S_Send(LPC_I2Sn_Type *I2Sx, uint32_t BufferData) {
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
|
||||
I2Sx->TXFIFO = BufferData;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief I2S Receive Data
|
||||
* @param[in] I2Sx pointer to LPC_I2Sn_Type, should be: LPC_I2S
|
||||
* @return received value
|
||||
*********************************************************************/
|
||||
uint32_t I2S_Receive(LPC_I2Sn_Type* I2Sx) {
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
|
||||
return (I2Sx->RXFIFO);
|
||||
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief I2S Pause
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] TRMode is transmit/receive mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void I2S_Pause(LPC_I2Sn_Type *I2Sx, uint8_t TRMode) {
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
|
||||
|
||||
if (TRMode == I2S_TX_MODE) //Transmit mode
|
||||
{
|
||||
I2Sx->DAO |= I2S_DAO_STOP;
|
||||
} else //Receive mode
|
||||
{
|
||||
I2Sx->DAI |= I2S_DAI_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief I2S Mute
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] TRMode is transmit/receive mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void I2S_Mute(LPC_I2Sn_Type *I2Sx, uint8_t TRMode) {
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
|
||||
|
||||
if (TRMode == I2S_TX_MODE) //Transmit mode
|
||||
{
|
||||
I2Sx->DAO |= I2S_DAO_MUTE;
|
||||
} else //Receive mode
|
||||
{
|
||||
I2Sx->DAI |= I2S_DAI_MUTE;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief I2S Stop
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] TRMode is transmit/receive mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void I2S_Stop(LPC_I2Sn_Type *I2Sx, uint8_t TRMode) {
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
|
||||
|
||||
if (TRMode == I2S_TX_MODE) //Transmit mode
|
||||
{
|
||||
I2Sx->DAO &= ~I2S_DAO_MUTE;
|
||||
I2Sx->DAO |= I2S_DAO_STOP;
|
||||
I2Sx->DAO |= I2S_DAO_RESET;
|
||||
} else //Receive mode
|
||||
{
|
||||
I2Sx->DAI |= I2S_DAI_STOP;
|
||||
I2Sx->DAI |= I2S_DAI_RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Set frequency for I2S
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] Freq is the frequency for I2S will be set. It can range
|
||||
* from 16-96 kHz(16, 22.05, 32, 44.1, 48, 96kHz)
|
||||
* @param[in] TRMode is transmit/receive mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @return Status: ERROR or SUCCESS
|
||||
*********************************************************************/
|
||||
Status I2S_FreqConfig(LPC_I2Sn_Type *I2Sx, uint32_t Freq, uint8_t TRMode) {
|
||||
|
||||
/* Calculate bit rate
|
||||
* The formula is:
|
||||
* bit_rate = channel*wordwidth - 1
|
||||
* 48kHz sample rate for 16 bit stereo date requires
|
||||
* a bit rate of 48000*16*2=1536MHz (MCLK)
|
||||
*/
|
||||
uint32_t i2sPclk;
|
||||
uint64_t divider;
|
||||
uint8_t bitrate, channel, wordwidth;
|
||||
uint32_t x, y;
|
||||
uint16_t dif;
|
||||
uint16_t error;
|
||||
uint16_t x_divide, y_divide;
|
||||
uint16_t ErrorOptimal = 0xFFFF;
|
||||
int32_t N;
|
||||
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
CHECK_PARAM(PRAM_I2S_FREQ(Freq));
|
||||
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
|
||||
|
||||
//LPC_CGU->BASE_VPB1_CLK = 0x08<<24 | AUTO_BLOCK;
|
||||
CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_APB1);
|
||||
i2sPclk = CGU_GetPCLKFrequency(CGU_PERIPHERAL_I2S);
|
||||
if(TRMode == I2S_TX_MODE)
|
||||
{
|
||||
channel = i2s_GetChannel(I2Sx,I2S_TX_MODE);
|
||||
wordwidth = i2s_GetWordWidth(I2Sx,I2S_TX_MODE);
|
||||
}
|
||||
else
|
||||
{
|
||||
channel = i2s_GetChannel(I2Sx,I2S_RX_MODE);
|
||||
wordwidth = i2s_GetWordWidth(I2Sx,I2S_RX_MODE);
|
||||
}
|
||||
bitrate = 2 * wordwidth - 1;
|
||||
|
||||
/* Calculate X and Y divider
|
||||
* The MCLK rate for the I2S transmitter is determined by the value
|
||||
* in the I2STXRATE/I2SRXRATE register. The required I2STXRATE/I2SRXRATE
|
||||
* setting depends on the desired audio sample rate desired, the format
|
||||
* (stereo/mono) used, and the data size.
|
||||
* The formula is:
|
||||
* I2S_MCLK = PCLK * (X/Y) / 2
|
||||
* We have:
|
||||
* I2S_MCLK = Freq * bit_rate * I2Sx->TXBITRATE;
|
||||
* So: (X/Y) = (Freq * bit_rate * I2Sx->TXBITRATE)/PCLK*2
|
||||
* We use a loop function to chose the most suitable X,Y value
|
||||
*/
|
||||
|
||||
/* divider is a fixed point number with 16 fractional bits */
|
||||
divider = ((uint64_t)(Freq *( bitrate+1) * 2)<<16) / i2sPclk;
|
||||
|
||||
/* find N that make x/y <= 1 -> divider <= 2^16 */
|
||||
for(N=64;N>0;N--){
|
||||
if((divider*N) < (1<<16)) break;
|
||||
}
|
||||
|
||||
if(N == 0) return ERROR;
|
||||
|
||||
divider *= N;
|
||||
|
||||
for (y = 255; y > 0; y--) {
|
||||
x = y * divider;
|
||||
if(x & (0xFF000000)) continue;
|
||||
dif = x & 0xFFFF;
|
||||
if(dif>0x8000) error = 0x10000-dif;
|
||||
else error = dif;
|
||||
if (error == 0)
|
||||
{
|
||||
y_divide = y;
|
||||
break;
|
||||
}
|
||||
else if (error < ErrorOptimal)
|
||||
{
|
||||
ErrorOptimal = error;
|
||||
y_divide = y;
|
||||
}
|
||||
}
|
||||
x_divide = ((uint64_t)y_divide * Freq *( bitrate+1)* N * 2)/i2sPclk;
|
||||
if(x_divide >= 256) x_divide = 0xFF;
|
||||
if(x_divide == 0) x_divide = 1;
|
||||
if (TRMode == I2S_TX_MODE)// Transmitter
|
||||
{
|
||||
I2Sx->TXBITRATE = N - 1;
|
||||
I2Sx->TXRATE = y_divide | (x_divide << 8);
|
||||
} else //Receiver
|
||||
{
|
||||
I2Sx->RXBITRATE = N - 1;
|
||||
I2Sx->RXRATE = y_divide | (x_divide << 8);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief I2S set bitrate
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] bitrate value will be set, it can be calculate as follows:
|
||||
* bitrate = channel * wordwidth - 1
|
||||
* bitrate value should be in range: 0 .. 63
|
||||
* @param[in] TRMode is transmit/receive mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void I2S_SetBitRate(LPC_I2Sn_Type *I2Sx, uint8_t bitrate, uint8_t TRMode)
|
||||
{
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
CHECK_PARAM(PARAM_I2S_BITRATE(bitrate));
|
||||
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
|
||||
|
||||
if(TRMode == I2S_TX_MODE)
|
||||
{
|
||||
I2Sx->TXBITRATE = bitrate;
|
||||
}
|
||||
else
|
||||
{
|
||||
I2Sx->RXBITRATE = bitrate;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Configuration operating mode for I2S
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] ModeConfig pointer to I2S_MODEConf_Type will be used to
|
||||
* configure
|
||||
* @param[in] TRMode is transmit/receive mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void I2S_ModeConfig(LPC_I2Sn_Type *I2Sx, I2S_MODEConf_Type* ModeConfig,
|
||||
uint8_t TRMode)
|
||||
{
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
CHECK_PARAM(PARAM_I2S_CLKSEL(ModeConfig->clksel));
|
||||
CHECK_PARAM(PARAM_I2S_4PIN(ModeConfig->fpin));
|
||||
CHECK_PARAM(PARAM_I2S_MCLK(ModeConfig->mcena));
|
||||
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
|
||||
|
||||
if (TRMode == I2S_TX_MODE) {
|
||||
I2Sx->TXMODE &= ~0x0F; //clear bit 3:0 in I2STXMODE register
|
||||
if (ModeConfig->clksel == I2S_CLKSEL_MCLK) {
|
||||
I2Sx->TXMODE |= 0x02;
|
||||
}
|
||||
if (ModeConfig->fpin == I2S_4PIN_ENABLE) {
|
||||
I2Sx->TXMODE |= (1 << 2);
|
||||
}
|
||||
if (ModeConfig->mcena == I2S_MCLK_ENABLE) {
|
||||
I2Sx->TXMODE |= (1 << 3);
|
||||
}
|
||||
} else {
|
||||
I2Sx->RXMODE &= ~0x0F; //clear bit 3:0 in I2STXMODE register
|
||||
if (ModeConfig->clksel == I2S_CLKSEL_MCLK) {
|
||||
I2Sx->RXMODE |= 0x02;
|
||||
}
|
||||
if (ModeConfig->fpin == I2S_4PIN_ENABLE) {
|
||||
I2Sx->RXMODE |= (1 << 2);
|
||||
}
|
||||
if (ModeConfig->mcena == I2S_MCLK_ENABLE) {
|
||||
I2Sx->RXMODE |= (1 << 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Configure DMA operation for I2S
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] DMAConfig pointer to I2S_DMAConf_Type will be used to configure
|
||||
* @param[in] TRMode is transmit/receive mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void I2S_DMAConfig(LPC_I2Sn_Type *I2Sx, I2S_DMAConf_Type* DMAConfig,
|
||||
uint8_t TRMode)
|
||||
{
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
CHECK_PARAM(PARAM_I2S_DMA(DMAConfig->DMAIndex));
|
||||
CHECK_PARAM(PARAM_I2S_DMA_DEPTH(DMAConfig->depth));
|
||||
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
|
||||
|
||||
if (TRMode == I2S_RX_MODE) {
|
||||
if (DMAConfig->DMAIndex == I2S_DMA_1) {
|
||||
I2Sx->DMA1 = (DMAConfig->depth) << 8;
|
||||
} else {
|
||||
I2Sx->DMA2 = (DMAConfig->depth) << 8;
|
||||
}
|
||||
} else {
|
||||
if (DMAConfig->DMAIndex == I2S_DMA_1) {
|
||||
I2Sx->DMA1 = (DMAConfig->depth) << 16;
|
||||
} else {
|
||||
I2Sx->DMA2 = (DMAConfig->depth) << 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Enable/Disable DMA operation for I2S
|
||||
* @param[in] I2Sx: I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] DMAIndex chose what DMA is used, should be:
|
||||
* - I2S_DMA_1 = 0 :DMA1
|
||||
* - I2S_DMA_2 = 1 :DMA2
|
||||
* @param[in] TRMode is transmit/receive mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @param[in] NewState is new state of DMA operation, should be:
|
||||
* - ENABLE
|
||||
* - DISABLE
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void I2S_DMACmd(LPC_I2Sn_Type *I2Sx, uint8_t DMAIndex, uint8_t TRMode,
|
||||
FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
|
||||
CHECK_PARAM(PARAM_I2S_DMA(DMAIndex));
|
||||
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
|
||||
|
||||
if (TRMode == I2S_RX_MODE) {
|
||||
if (DMAIndex == I2S_DMA_1) {
|
||||
if (NewState == ENABLE)
|
||||
I2Sx->DMA1 |= 0x01;
|
||||
else
|
||||
I2Sx->DMA1 &= ~0x01;
|
||||
} else {
|
||||
if (NewState == ENABLE)
|
||||
I2Sx->DMA2 |= 0x01;
|
||||
else
|
||||
I2Sx->DMA2 &= ~0x01;
|
||||
}
|
||||
} else {
|
||||
if (DMAIndex == I2S_DMA_1) {
|
||||
if (NewState == ENABLE)
|
||||
I2Sx->DMA1 |= 0x02;
|
||||
else
|
||||
I2Sx->DMA1 &= ~0x02;
|
||||
} else {
|
||||
if (NewState == ENABLE)
|
||||
I2Sx->DMA2 |= 0x02;
|
||||
else
|
||||
I2Sx->DMA2 &= ~0x02;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Configure IRQ for I2S
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] TRMode is transmit/receive mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @param[in] level is the FIFO level that triggers IRQ request
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void I2S_IRQConfig(LPC_I2Sn_Type *I2Sx, uint8_t TRMode, uint8_t level) {
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
CHECK_PARAM(PARAM_I2S_TRX(TRMode));
|
||||
CHECK_PARAM(PARAM_I2S_IRQ_LEVEL(level));
|
||||
|
||||
if (TRMode == I2S_RX_MODE) {
|
||||
I2Sx->IRQ |= (level << 8);
|
||||
} else {
|
||||
I2Sx->IRQ |= (level << 16);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Enable/Disable IRQ for I2S
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] TRMode is transmit/receive mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @param[in] NewState is new state of DMA operation, should be:
|
||||
* - ENABLE
|
||||
* - DISABLE
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void I2S_IRQCmd(LPC_I2Sn_Type *I2Sx, uint8_t TRMode, FunctionalState NewState) {
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
|
||||
|
||||
if (TRMode == I2S_RX_MODE) {
|
||||
if (NewState == ENABLE)
|
||||
I2Sx->IRQ |= 0x01;
|
||||
else
|
||||
I2Sx->IRQ &= ~0x01;
|
||||
//Enable DMA
|
||||
|
||||
} else {
|
||||
if (NewState == ENABLE)
|
||||
I2Sx->IRQ |= 0x02;
|
||||
else
|
||||
I2Sx->IRQ &= ~0x02;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Get I2S interrupt status
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] TRMode is transmit/receive mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @return FunctionState should be:
|
||||
* - ENABLE :interrupt is enable
|
||||
* - DISABLE :interrupt is disable
|
||||
*********************************************************************/
|
||||
FunctionalState I2S_GetIRQStatus(LPC_I2Sn_Type *I2Sx,uint8_t TRMode)
|
||||
{
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
if(TRMode == I2S_TX_MODE)
|
||||
return (FunctionalState)((I2Sx->IRQ >> 1)&0x01);
|
||||
else
|
||||
return (FunctionalState)((I2Sx->IRQ)&0x01);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Get I2S interrupt depth
|
||||
* @param[in] I2Sx I2S peripheral selected, should be: LPC_I2S
|
||||
* @param[in] TRMode is transmit/receive mode, should be:
|
||||
* - I2S_TX_MODE = 0 :transmit mode
|
||||
* - I2S_RX_MODE = 1 :receive mode
|
||||
* @return depth of FIFO level on which to create an irq request
|
||||
*********************************************************************/
|
||||
uint8_t I2S_GetIRQDepth(LPC_I2Sn_Type *I2Sx,uint8_t TRMode)
|
||||
{
|
||||
CHECK_PARAM(PARAM_I2Sx(I2Sx));
|
||||
if(TRMode == I2S_TX_MODE)
|
||||
return (((I2Sx->IRQ)>>16)&0xFF);
|
||||
else
|
||||
return (((I2Sx->IRQ)>>8)&0xFF);
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _I2S */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* --------------------------------- End Of File ------------------------------ */
|
||||
@@ -0,0 +1,472 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_lcd.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_lcd.c
|
||||
* @brief Contains all function support for LCD Driver
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors�
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup LCD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "LPC43xx.h"
|
||||
#include "lpc43xx_lcd.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
#ifdef _LCD
|
||||
|
||||
LCD_CURSOR_SIZE_OPT LCD_Cursor_Size = LCD_CURSOR_64x64;
|
||||
|
||||
/* Private Functions ---------------------------------------------------------- */
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Init the lpc43xx LCD Controller
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] LCD_ConfigStruct point to LCD_CFG_Type that describe the LCD Panel
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_Init(LPC_LCD_Type *LCDx, LCD_CFG_Type *LCD_ConfigStruct){
|
||||
uint32_t i, regValue, *pPal;
|
||||
uint32_t pcd;
|
||||
/* disable the display */
|
||||
LCDx->CTRL &= ~CLCDC_LCDCTRL_ENABLE;
|
||||
|
||||
/* Setting LCD_TIMH register */
|
||||
regValue= ( ((((LCD_ConfigStruct->screen_width/16)-1)&0x3F) << 2)
|
||||
| (( (LCD_ConfigStruct->HSync_pulse_width-1) &0xFF) << 8)
|
||||
| (( (LCD_ConfigStruct->horizontal_porch.front-1) &0xFF) << 16)
|
||||
| (( (LCD_ConfigStruct->horizontal_porch.back-1) &0xFF) << 24) );
|
||||
|
||||
LCDx->TIMH = regValue;
|
||||
|
||||
/* Setting LCD_TIMV register */
|
||||
regValue =((((LCD_ConfigStruct->screen_height-1) &0x3FF) << 0)
|
||||
| (((LCD_ConfigStruct->VSync_pulse_width-1) &0x03F) << 10)
|
||||
| (((LCD_ConfigStruct->vertical_porch.front-1) &0x0FF) << 16)
|
||||
| (((LCD_ConfigStruct->vertical_porch.back-1) &0x0FF) << 24) );
|
||||
|
||||
LCDx->TIMV = regValue;
|
||||
|
||||
/* Generate the clock and signal polarity control word */
|
||||
regValue = 0;
|
||||
regValue = (((LCD_ConfigStruct->ac_bias_frequency-1) & 0x1F) << 6);
|
||||
|
||||
regValue |= (LCD_ConfigStruct->OE_pol & 1)<< 14;
|
||||
|
||||
regValue |= (LCD_ConfigStruct->panel_clk_edge & 1)<< 13;
|
||||
|
||||
regValue |= (LCD_ConfigStruct->HSync_pol & 1)<< 12;
|
||||
|
||||
regValue |= (LCD_ConfigStruct->VSync_pol & 1)<< 11;
|
||||
|
||||
/* Compute clocks per line based on panel type */
|
||||
|
||||
switch(LCD_ConfigStruct->lcd_panel_type)
|
||||
{
|
||||
case LCD_MONO_4:
|
||||
regValue |= ((((LCD_ConfigStruct->screen_width / 4)-1) & 0x3FF) << 16);
|
||||
break;
|
||||
case LCD_MONO_8:
|
||||
regValue |= ((((LCD_ConfigStruct->screen_width / 8)-1) & 0x3FF) << 16);
|
||||
break;
|
||||
case LCD_CSTN:
|
||||
regValue |= (((((LCD_ConfigStruct->screen_width * 3)/8)-1) & 0x3FF) << 16);
|
||||
break;
|
||||
case LCD_TFT:
|
||||
default:
|
||||
regValue |= /* 1<<26 |*/ (((LCD_ConfigStruct->screen_width-1) & 0x3FF) << 16);
|
||||
}
|
||||
|
||||
/* panel clock divisor */
|
||||
pcd = 6; // TODO: should be calculated from LCDDCLK
|
||||
pcd &= 0x3FF;
|
||||
regValue |= ((pcd>>5)<<27) | ((pcd)&0x1F);
|
||||
|
||||
LCDx->POL = regValue;
|
||||
|
||||
/* configure line end control */
|
||||
CHECK_PARAM(LCD_ConfigStruct->line_end_delay<=(1<<7));
|
||||
if(LCD_ConfigStruct->line_end_delay)
|
||||
LCDx->LE = (LCD_ConfigStruct->line_end_delay-1) | 1<<16;
|
||||
else
|
||||
LCDx->LE = 0;
|
||||
|
||||
/* disable interrupts */
|
||||
LCDx->INTMSK = 0;
|
||||
|
||||
/* set bits per pixel */
|
||||
regValue = LCD_ConfigStruct->bits_per_pixel << 1;
|
||||
|
||||
/* set color format BGR or RGB */
|
||||
regValue |= LCD_ConfigStruct->corlor_format << 8;
|
||||
|
||||
regValue |= LCD_ConfigStruct->lcd_panel_type << 4;
|
||||
|
||||
if(LCD_ConfigStruct->dual_panel == 1)
|
||||
{
|
||||
regValue |= 1 << 7;
|
||||
}
|
||||
LCDx->CTRL = regValue;
|
||||
/* clear palette */
|
||||
pPal = (uint32_t*) (&(LCDx->PAL));
|
||||
|
||||
for(i = 0; i < 128; i++)
|
||||
{
|
||||
*pPal = 0;
|
||||
pPal++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Deinit LCD controller
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_DeInit(LPC_LCD_Type *LCDx);
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Power the LCD Panel
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] OnOff Turn on/off LCD
|
||||
* - TRUE :Turn on
|
||||
* - FALSE :Turn off
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_Power(LPC_LCD_Type *LCDx, FunctionalState OnOff){
|
||||
int i;
|
||||
if(OnOff){
|
||||
LPC_LCD->CTRL |= CLCDC_LCDCTRL_PWR;
|
||||
for(i=0;i<100000;i++);
|
||||
LPC_LCD->CTRL |= CLCDC_LCDCTRL_ENABLE;
|
||||
}else{
|
||||
LPC_LCD->CTRL &= ~CLCDC_LCDCTRL_PWR;
|
||||
for(i=0;i<100000;i++);
|
||||
LPC_LCD->CTRL &= ~CLCDC_LCDCTRL_ENABLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable/Disable the LCD Controller
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] EnDis Enable/disable status
|
||||
* - TRUE :Enable
|
||||
* - FALSE :Disable
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_Enable(LPC_LCD_Type *LCDx, FunctionalState EnDis){
|
||||
if (EnDis)
|
||||
{
|
||||
LCDx->CTRL |= CLCDC_LCDCTRL_ENABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDx->CTRL &= ~CLCDC_LCDCTRL_ENABLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set LCD Frame Buffer for Single Panel or Upper Panel Frame
|
||||
* Buffer for Dual Panel
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] buffer address of buffer
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_SetFrameBuffer(LPC_LCD_Type *LCDx, void* buffer){
|
||||
LCDx->UPBASE = (uint32_t)buffer;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set LCD Lower Panel Frame Buffer for Dual Panel
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] buffer address of buffer
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_SetLPFrameBuffer(LPC_LCD_Type *LCDx, void* buffer){
|
||||
LCDx->LPBASE = (uint32_t)buffer;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Configure Cursor
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] cursor_size specify size of cursor
|
||||
* - LCD_CURSOR_32x32 :cursor size is 32x32 pixels
|
||||
* - LCD_CURSOR_64x64 :cursor size is 64x64 pixels
|
||||
* @param[in] sync cursor sync mode
|
||||
* - TRUE :cursor sync to the frame sync pulse
|
||||
* - FALSE :cursor async mode
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_Cursor_Config(LPC_LCD_Type *LCDx, LCD_CURSOR_SIZE_OPT cursor_size, Bool sync){
|
||||
LCD_Cursor_Size = cursor_size;
|
||||
LCDx->CRSR_CFG = ((sync?1:0)<<1) | cursor_size;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Write Cursor Image into Internal Cursor Image Buffer
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] cursor_num specify number of cursor is going to be written
|
||||
* this param must < 4
|
||||
* @param[in] Image point to Cursor Image Buffer
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_Cursor_WriteImage(LPC_LCD_Type *LCDx, uint8_t cursor_num, void* Image){
|
||||
int i,j;
|
||||
uint8_t *fifoptr, *crsr_ptr = (uint8_t *)Image;
|
||||
|
||||
CHECK_PARAM(cursor_num<4);
|
||||
/* Check if Cursor Size was configured as 32x32 or 64x64*/
|
||||
if(LCD_Cursor_Size == LCD_CURSOR_32x32){
|
||||
i = cursor_num * 256;
|
||||
j = i + 256;
|
||||
}else{
|
||||
i = 0;
|
||||
j = 1024;
|
||||
}
|
||||
fifoptr = (uint8_t*)&(LCDx->CRSR_IMG[0]);
|
||||
/* Copy Cursor Image content to FIFO */
|
||||
for(; i < j; i++)
|
||||
{
|
||||
fifoptr[i] = *(uint8_t *)crsr_ptr;
|
||||
crsr_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get Internal Cursor Image Buffer Address
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] cursor_num specify number of cursor is going to be written
|
||||
* this param must < 4
|
||||
* @return Cursor Image Buffer Address
|
||||
**********************************************************************/
|
||||
void* LCD_Cursor_GetImageBufferAddress(LPC_LCD_Type *LCDx, uint8_t cursor_num){
|
||||
CHECK_PARAM(cursor_num<4);
|
||||
return (void*)&(LCDx->CRSR_IMG[cursor_num*64]);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable Cursor
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] cursor_num specify number of cursor is going to be written
|
||||
* this param must < 4
|
||||
* @param[in] OnOff Turn on/off LCD
|
||||
* - TRUE :Enable
|
||||
* - FALSE :Disable
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_Cursor_Enable(LPC_LCD_Type *LCDx, uint8_t cursor_num, FunctionalState OnOff){
|
||||
CHECK_PARAM(cursor_num<4);
|
||||
if (OnOff)
|
||||
{
|
||||
LCDx->CRSR_CTRL = (cursor_num<<4) | 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDx->CRSR_CTRL = (cursor_num<<4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Load LCD Palette
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] palette point to palette address
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_LoadPalette(LPC_LCD_Type *LCDx, void* palette){
|
||||
LCD_PALETTE_ENTRY_Type pal_entry, *ptr_pal_entry;
|
||||
uint8_t i, *pal_ptr;
|
||||
/* This function supports loading of the color palette from
|
||||
the C file generated by the bmp2c utility. It expects the
|
||||
palette to be passed as an array of 32-bit BGR entries having
|
||||
the following format:
|
||||
2:0 - Not used
|
||||
7:3 - Blue
|
||||
10:8 - Not used
|
||||
15:11 - Green
|
||||
18:16 - Not used
|
||||
23:19 - Red
|
||||
31:24 - Not used
|
||||
arg = pointer to input palette table address */
|
||||
ptr_pal_entry = &pal_entry;
|
||||
pal_ptr = (uint8_t *) palette;
|
||||
|
||||
/* 256 entry in the palette table */
|
||||
for(i = 0; i < 256/2; i++)
|
||||
{
|
||||
pal_entry.Bl = (*pal_ptr++) >> 3; /* blue first */
|
||||
pal_entry.Gl = (*pal_ptr++) >> 3; /* get green */
|
||||
pal_entry.Rl = (*pal_ptr++) >> 3; /* get red */
|
||||
pal_ptr++; /* skip over the unused byte */
|
||||
/* do the most significant halfword of the palette */
|
||||
pal_entry.Bu = (*pal_ptr++) >> 3; /* blue first */
|
||||
pal_entry.Gu = (*pal_ptr++) >> 3; /* get green */
|
||||
pal_entry.Ru = (*pal_ptr++) >> 3; /* get red */
|
||||
pal_ptr++; /* skip over the unused byte */
|
||||
|
||||
LCDx->PAL[i] = *(uint32_t *)ptr_pal_entry;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Load Cursor Palette
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] palette_color cursor palette 0 value
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_Cursor_LoadPalette0(LPC_LCD_Type *LCDx, uint32_t palette_color){
|
||||
/* 7:0 - Red
|
||||
15:8 - Green
|
||||
23:16 - Blue
|
||||
31:24 - Not used*/
|
||||
LCDx->CRSR_PAL0 = (uint32_t)palette_color;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Load Cursor Palette
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] palette_color cursor palette 1 value
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_Cursor_LoadPalette1(LPC_LCD_Type *LCDx, uint32_t palette_color){
|
||||
/* 7:0 - Red
|
||||
15:8 - Green
|
||||
23:16 - Blue
|
||||
31:24 - Not used*/
|
||||
LCDx->CRSR_PAL1 = (uint32_t)palette_color;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set Interrupt
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] Int LCD Interrupt Source, should be:
|
||||
* - LCD_INT_FUF :FIFO underflow
|
||||
* - LCD_INT_LNBU :LCD next base address update bit
|
||||
* - LCD_INT_VCOMP :Vertical compare bit
|
||||
* - LCD_INT_BER :AHB master error interrupt bit
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_SetInterrupt(LPC_LCD_Type *LCDx, LCD_INT_SRC Int){
|
||||
LCDx->INTMSK |= Int;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Clear Interrupt
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] Int LCD Interrupt Source, should be:
|
||||
* - LCD_INT_FUF :FIFO underflow
|
||||
* - LCD_INT_LNBU :LCD next base address update bit
|
||||
* - LCD_INT_VCOMP :Vertical compare bit
|
||||
* - LCD_INT_BER :AHB master error interrupt bit
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_ClrInterrupt(LPC_LCD_Type *LCDx, LCD_INT_SRC Int){
|
||||
LCDx->INTCLR |= Int;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get LCD Interrupt Status
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
LCD_INT_SRC LCD_GetInterrupt(LPC_LCD_Type *LCDx){
|
||||
return (LCD_INT_SRC)LCDx->INTRAW;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable Cursor Interrupt
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_Cursor_SetInterrupt(LPC_LCD_Type *LCDx){
|
||||
LCDx->CRSR_INTMSK |= 1;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Clear Cursor Interrupt
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_Cursor_ClrInterrupt(LPC_LCD_Type *LCDx){
|
||||
LCDx->CRSR_INTCLR |= 1;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set Cursor Position
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] x horizontal position
|
||||
* @param[in] y vertical position
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_Cursor_SetPos(LPC_LCD_Type *LCDx, uint16_t x, uint16_t y){
|
||||
LCDx->CRSR_XY = (x & 0x3FF) | ((y & 0x3FF) << 16);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set Cursor Clipping Position
|
||||
* @param[in] LCDx pointer to LCD Controller Reg Struct, should be: LPC_LCD
|
||||
* @param[in] x horizontal position, should be in range: 0..63
|
||||
* @param[in] y vertical position, should be in range: 0..63
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void LCD_Cursor_SetClip(LPC_LCD_Type *LCDx, uint16_t x, uint16_t y){
|
||||
LCDx->CRSR_CLIP = (x & 0x3F) | ((y & 0x3F) << 8);
|
||||
}
|
||||
#endif /* _LCD */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,560 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_mcpwm.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_mcpwm.c
|
||||
* @brief Contains all functions support for Motor Control PWM firmware
|
||||
* library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup MCPWM
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_mcpwm.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
#ifdef _MCPWM
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup MCPWM_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Initializes the MCPWM peripheral
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void MCPWM_Init(LPC_MCPWM_Type *MCPWMx)
|
||||
{
|
||||
/* Turn On MCPWM PCLK */
|
||||
//LPC_CGU->BASE_VPB1_CLK = (SRC_PL160M_0<<24) | (1<<11);
|
||||
CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_APB1);
|
||||
|
||||
MCPWMx->CAP_CLR = MCPWM_CAPCLR_CAP(0) | MCPWM_CAPCLR_CAP(1) | MCPWM_CAPCLR_CAP(2);
|
||||
|
||||
MCPWMx->INTF_CLR = MCPWM_INT_ILIM(0) | MCPWM_INT_ILIM(1) | MCPWM_INT_ILIM(2) \
|
||||
| MCPWM_INT_IMAT(0) | MCPWM_INT_IMAT(1) | MCPWM_INT_IMAT(2) \
|
||||
| MCPWM_INT_ICAP(0) | MCPWM_INT_ICAP(1) | MCPWM_INT_ICAP(2);
|
||||
|
||||
MCPWMx->INTEN_CLR = MCPWM_INT_ILIM(0) | MCPWM_INT_ILIM(1) | MCPWM_INT_ILIM(2) \
|
||||
| MCPWM_INT_IMAT(0) | MCPWM_INT_IMAT(1) | MCPWM_INT_IMAT(2) \
|
||||
| MCPWM_INT_ICAP(0) | MCPWM_INT_ICAP(1) | MCPWM_INT_ICAP(2);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Configures each channel in MCPWM peripheral according to the
|
||||
* specified parameters in the MCPWM_CHANNEL_CFG_Type.
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @param[in] channelNum Channel number, should be: 0..2.
|
||||
* @param[in] channelSetup Pointer to a MCPWM_CHANNEL_CFG_Type structure
|
||||
* that contains the configuration information for the specified
|
||||
* MCPWM channel.
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void MCPWM_ConfigChannel(LPC_MCPWM_Type *MCPWMx, uint32_t channelNum,
|
||||
MCPWM_CHANNEL_CFG_Type * channelSetup)
|
||||
{
|
||||
if (channelNum <= 2)
|
||||
{
|
||||
if (channelNum == MCPWM_CHANNEL_0)
|
||||
{
|
||||
MCPWMx->TC[0] = channelSetup->channelTimercounterValue;
|
||||
MCPWMx->LIM[0] = channelSetup->channelPeriodValue;
|
||||
MCPWMx->MAT[0] = channelSetup->channelPulsewidthValue;
|
||||
}
|
||||
else if (channelNum == MCPWM_CHANNEL_1)
|
||||
{
|
||||
MCPWMx->TC[1] = channelSetup->channelTimercounterValue;
|
||||
MCPWMx->LIM[1] = channelSetup->channelPeriodValue;
|
||||
MCPWMx->MAT[1] = channelSetup->channelPulsewidthValue;
|
||||
}
|
||||
else if (channelNum == MCPWM_CHANNEL_2)
|
||||
{
|
||||
MCPWMx->TC[2] = channelSetup->channelTimercounterValue;
|
||||
MCPWMx->LIM[2] = channelSetup->channelPeriodValue;
|
||||
MCPWMx->MAT[2] = channelSetup->channelPulsewidthValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (channelSetup->channelType == MCPWM_CHANNEL_CENTER_MODE)
|
||||
{
|
||||
MCPWMx->CON_SET = MCPWM_CON_CENTER(channelNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->CON_CLR = MCPWM_CON_CENTER(channelNum);
|
||||
}
|
||||
|
||||
if (channelSetup->channelPolarity == MCPWM_CHANNEL_PASSIVE_HI)
|
||||
{
|
||||
MCPWMx->CON_SET = MCPWM_CON_POLAR(channelNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->CON_CLR = MCPWM_CON_POLAR(channelNum);
|
||||
}
|
||||
|
||||
if (channelSetup->channelDeadtimeEnable == ENABLE)
|
||||
{
|
||||
MCPWMx->CON_SET = MCPWM_CON_DTE(channelNum);
|
||||
|
||||
MCPWMx->DT &= ~(MCPWM_DT(channelNum, 0x3FF));
|
||||
|
||||
MCPWMx->DT |= MCPWM_DT(channelNum, channelSetup->channelDeadtimeValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->CON_CLR = MCPWM_CON_DTE(channelNum);
|
||||
}
|
||||
|
||||
if (channelSetup->channelUpdateEnable == ENABLE)
|
||||
{
|
||||
MCPWMx->CON_CLR = MCPWM_CON_DISUP(channelNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->CON_SET = MCPWM_CON_DISUP(channelNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Write to MCPWM shadow registers - Update the value for period
|
||||
* and pulse width in MCPWM peripheral.
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @param[in] channelNum Channel Number, should be: 0..2.
|
||||
* @param[in] channelSetup Pointer to a MCPWM_CHANNEL_CFG_Type structure
|
||||
* that contains the configuration information for the specified
|
||||
* MCPWM channel.
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void MCPWM_WriteToShadow(LPC_MCPWM_Type *MCPWMx, uint32_t channelNum,
|
||||
MCPWM_CHANNEL_CFG_Type *channelSetup)
|
||||
{
|
||||
if (channelNum == MCPWM_CHANNEL_0)
|
||||
{
|
||||
MCPWMx->LIM[0] = channelSetup->channelPeriodValue;
|
||||
MCPWMx->MAT[0] = channelSetup->channelPulsewidthValue;
|
||||
}
|
||||
else if (channelNum == MCPWM_CHANNEL_1)
|
||||
{
|
||||
MCPWMx->LIM[1] = channelSetup->channelPeriodValue;
|
||||
MCPWMx->MAT[1] = channelSetup->channelPulsewidthValue;
|
||||
}
|
||||
else if (channelNum == MCPWM_CHANNEL_2)
|
||||
{
|
||||
MCPWMx->LIM[2] = channelSetup->channelPeriodValue;
|
||||
MCPWMx->MAT[2] = channelSetup->channelPulsewidthValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Configures capture function in MCPWM peripheral
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @param[in] channelNum MCI (Motor Control Input pin) number, should be: 0..2
|
||||
* @param[in] captureConfig Pointer to a MCPWM_CAPTURE_CFG_Type structure
|
||||
* that contains the configuration information for the
|
||||
* specified MCPWM capture.
|
||||
* @return
|
||||
**********************************************************************/
|
||||
void MCPWM_ConfigCapture(LPC_MCPWM_Type *MCPWMx, uint32_t channelNum,
|
||||
MCPWM_CAPTURE_CFG_Type *captureConfig)
|
||||
{
|
||||
if ((channelNum <= MCPWM_CHANNEL_2))
|
||||
{
|
||||
|
||||
if (captureConfig->captureFalling == ENABLE)
|
||||
{
|
||||
MCPWMx->CAPCON_SET = MCPWM_CAPCON_CAPMCI_FE(captureConfig->captureChannel, channelNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->CAPCON_CLR = MCPWM_CAPCON_CAPMCI_FE(captureConfig->captureChannel, channelNum);
|
||||
}
|
||||
|
||||
if (captureConfig->captureRising == ENABLE)
|
||||
{
|
||||
MCPWMx->CAPCON_SET = MCPWM_CAPCON_CAPMCI_RE(captureConfig->captureChannel, channelNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->CAPCON_CLR = MCPWM_CAPCON_CAPMCI_RE(captureConfig->captureChannel, channelNum);
|
||||
}
|
||||
|
||||
if (captureConfig->timerReset == ENABLE)
|
||||
{
|
||||
MCPWMx->CAPCON_SET = MCPWM_CAPCON_RT(captureConfig->captureChannel);
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->CAPCON_CLR = MCPWM_CAPCON_RT(captureConfig->captureChannel);
|
||||
}
|
||||
|
||||
if (captureConfig->hnfEnable == ENABLE)
|
||||
{
|
||||
MCPWMx->CAPCON_SET = MCPWM_CAPCON_HNFCAP(channelNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->CAPCON_CLR = MCPWM_CAPCON_HNFCAP(channelNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Clears current captured value in specified capture channel
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @param[in] captureChannel Capture channel number, should be: 0..2
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void MCPWM_ClearCapture(LPC_MCPWM_Type *MCPWMx, uint32_t captureChannel)
|
||||
{
|
||||
MCPWMx->CAP_CLR = MCPWM_CAPCLR_CAP(captureChannel);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get current captured value in specified capture channel
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @param[in] captureChannel Capture channel number, should be: 0..2
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
uint32_t MCPWM_GetCapture(LPC_MCPWM_Type *MCPWMx, uint32_t captureChannel)
|
||||
{
|
||||
if (captureChannel == MCPWM_CHANNEL_0)
|
||||
{
|
||||
return (MCPWMx->CAP[0]);
|
||||
}
|
||||
else if (captureChannel == MCPWM_CHANNEL_1)
|
||||
{
|
||||
return (MCPWMx->CAP[1]);
|
||||
}
|
||||
else if (captureChannel == MCPWM_CHANNEL_2)
|
||||
{
|
||||
return (MCPWMx->CAP[2]);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Configures Count control in MCPWM peripheral
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @param[in] channelNum Channel number, should be: 0..2
|
||||
* @param[in] countMode Count mode, should be:
|
||||
* - ENABLE: Enables count mode.
|
||||
* - DISABLE: Disable count mode, the channel is in timer mode.
|
||||
* @param[in] countConfig Pointer to a MCPWM_COUNT_CFG_Type structure
|
||||
* that contains the configuration information for the
|
||||
* specified MCPWM count control.
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void MCPWM_CountConfig(LPC_MCPWM_Type *MCPWMx, uint32_t channelNum,
|
||||
uint32_t countMode, MCPWM_COUNT_CFG_Type *countConfig)
|
||||
{
|
||||
if ((channelNum <= 2))
|
||||
{
|
||||
if (countMode == ENABLE)
|
||||
{
|
||||
MCPWMx->CNTCON_SET = MCPWM_CNTCON_CNTR(channelNum);
|
||||
|
||||
if (countConfig->countFalling == ENABLE)
|
||||
{
|
||||
MCPWMx->CNTCON_SET = MCPWM_CNTCON_TCMCI_FE(countConfig->counterChannel,channelNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->CNTCON_CLR = MCPWM_CNTCON_TCMCI_FE(countConfig->counterChannel,channelNum);
|
||||
}
|
||||
|
||||
if (countConfig->countRising == ENABLE)
|
||||
{
|
||||
MCPWMx->CNTCON_SET = MCPWM_CNTCON_TCMCI_RE(countConfig->counterChannel,channelNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->CNTCON_CLR = MCPWM_CNTCON_TCMCI_RE(countConfig->counterChannel,channelNum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->CNTCON_CLR = MCPWM_CNTCON_CNTR(channelNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Start MCPWM activity for each MCPWM channel
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @param[in] channel0 State of this command on channel 0:
|
||||
* - ENABLE: 'Start' command will effect on channel 0
|
||||
* - DISABLE: 'Start' command will not effect on channel 0
|
||||
* @param[in] channel1 State of this command on channel 1:
|
||||
* - ENABLE: 'Start' command will effect on channel 1
|
||||
* - DISABLE: 'Start' command will not effect on channel 1
|
||||
* @param[in] channel2 State of this command on channel 2:
|
||||
* - ENABLE: 'Start' command will effect on channel 2
|
||||
* - DISABLE: 'Start' command will not effect on channel 2
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void MCPWM_Start(LPC_MCPWM_Type *MCPWMx, uint32_t channel0,
|
||||
uint32_t channel1, uint32_t channel2)
|
||||
{
|
||||
uint32_t regVal = 0;
|
||||
|
||||
regVal = (channel0 ? MCPWM_CON_RUN(0) : 0) | (channel1 ? MCPWM_CON_RUN(1) : 0) \
|
||||
| (channel2 ? MCPWM_CON_RUN(2) : 0);
|
||||
|
||||
MCPWMx->CON_SET = regVal;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Stop MCPWM activity for each MCPWM channel
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @param[in] channel0 State of this command on channel 0:
|
||||
* - ENABLE: 'Stop' command will effect on channel 0
|
||||
* - DISABLE: 'Stop' command will not effect on channel 0
|
||||
* @param[in] channel1 State of this command on channel 1:
|
||||
* - ENABLE: 'Stop' command will effect on channel 1
|
||||
* - DISABLE: 'Stop' command will not effect on channel 1
|
||||
* @param[in] channel2 State of this command on channel 2:
|
||||
* - ENABLE: 'Stop' command will effect on channel 2
|
||||
* - DISABLE: 'Stop' command will not effect on channel 2
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void MCPWM_Stop(LPC_MCPWM_Type *MCPWMx, uint32_t channel0,
|
||||
uint32_t channel1, uint32_t channel2)
|
||||
{
|
||||
uint32_t regVal = 0;
|
||||
|
||||
regVal = (channel0 ? MCPWM_CON_RUN(0) : 0) | (channel1 ? MCPWM_CON_RUN(1) : 0) \
|
||||
| (channel2 ? MCPWM_CON_RUN(2) : 0);
|
||||
|
||||
MCPWMx->CON_CLR = regVal;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enables/Disables 3-phase AC motor mode on MCPWM peripheral
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @param[in] acMode State of this command, should be:
|
||||
* - ENABLE.
|
||||
* - DISABLE.
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void MCPWM_ACMode(LPC_MCPWM_Type *MCPWMx, uint32_t acMode)
|
||||
{
|
||||
if (acMode)
|
||||
{
|
||||
MCPWMx->CON_SET = MCPWM_CON_ACMODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->CON_CLR = MCPWM_CON_ACMODE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enables/Disables 3-phase DC motor mode on MCPWM peripheral
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @param[in] dcMode State of this command, should be:
|
||||
* - ENABLE.
|
||||
* - DISABLE.
|
||||
* @param[in] outputInvered Polarity of the MCOB outputs for all 3 channels,
|
||||
* should be:
|
||||
* - ENABLE :The MCOB outputs have opposite polarity from the MCOA outputs.
|
||||
* - DISABLE :The MCOB outputs have the same basic polarity as the MCOA outputs.
|
||||
* @param[in] outputPattern A value contains bits that enables/disables the specified
|
||||
* output pins route to the internal MCOA0 signal, should be:
|
||||
* - MCPWM_PATENT_A0 :MCOA0 tracks internal MCOA0
|
||||
* - MCPWM_PATENT_B0 :MCOB0 tracks internal MCOA0
|
||||
* - MCPWM_PATENT_A1 :MCOA1 tracks internal MCOA0
|
||||
* - MCPWM_PATENT_B1 :MCOB1 tracks internal MCOA0
|
||||
* - MCPWM_PATENT_A2 :MCOA2 tracks internal MCOA0
|
||||
* - MCPWM_PATENT_B2 :MCOB2 tracks internal MCOA0
|
||||
* @return None
|
||||
*
|
||||
* Note: all these outputPatent values above can be ORed together for using as input parameter.
|
||||
**********************************************************************/
|
||||
void MCPWM_DCMode(LPC_MCPWM_Type *MCPWMx, uint32_t dcMode,
|
||||
uint32_t outputInvered, uint32_t outputPattern)
|
||||
{
|
||||
if (dcMode)
|
||||
{
|
||||
MCPWMx->CON_SET = MCPWM_CON_DCMODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->CON_CLR = MCPWM_CON_DCMODE;
|
||||
}
|
||||
|
||||
if (outputInvered)
|
||||
{
|
||||
MCPWMx->CON_SET = MCPWM_CON_INVBDC;
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->CON_CLR = MCPWM_CON_INVBDC;
|
||||
}
|
||||
|
||||
MCPWMx->CCP = outputPattern;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Configures the specified interrupt in MCPWM peripheral
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @param[in] ulIntType Interrupt type, should be:
|
||||
* - MCPWM_INTFLAG_LIM0 :Limit interrupt for channel (0)
|
||||
* - MCPWM_INTFLAG_MAT0 :Match interrupt for channel (0)
|
||||
* - MCPWM_INTFLAG_CAP0 :Capture interrupt for channel (0)
|
||||
* - MCPWM_INTFLAG_LIM1 :Limit interrupt for channel (1)
|
||||
* - MCPWM_INTFLAG_MAT1 :Match interrupt for channel (1)
|
||||
* - MCPWM_INTFLAG_CAP1 :Capture interrupt for channel (1)
|
||||
* - MCPWM_INTFLAG_LIM2 :Limit interrupt for channel (2)
|
||||
* - MCPWM_INTFLAG_MAT2 :Match interrupt for channel (2)
|
||||
* - MCPWM_INTFLAG_CAP2 :Capture interrupt for channel (2)
|
||||
* - MCPWM_INTFLAG_ABORT :Fast abort interrupt
|
||||
* @param[in] NewState New State of this command, should be:
|
||||
* - ENABLE.
|
||||
* - DISABLE.
|
||||
* @return None
|
||||
*
|
||||
* Note: all these ulIntType values above can be ORed together for using as input parameter.
|
||||
**********************************************************************/
|
||||
void MCPWM_IntConfig(LPC_MCPWM_Type *MCPWMx, uint32_t ulIntType, FunctionalState NewState)
|
||||
{
|
||||
if (NewState)
|
||||
{
|
||||
MCPWMx->INTEN_SET = ulIntType;
|
||||
}
|
||||
else
|
||||
{
|
||||
MCPWMx->INTEN_CLR = ulIntType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Sets/Forces the specified interrupt for MCPWM peripheral
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @param[in] ulIntType Interrupt type, should be:
|
||||
* - MCPWM_INTFLAG_LIM0 :Limit interrupt for channel (0)
|
||||
* - MCPWM_INTFLAG_MAT0 :Match interrupt for channel (0)
|
||||
* - MCPWM_INTFLAG_CAP0 :Capture interrupt for channel (0)
|
||||
* - MCPWM_INTFLAG_LIM1 :Limit interrupt for channel (1)
|
||||
* - MCPWM_INTFLAG_MAT1 :Match interrupt for channel (1)
|
||||
* - MCPWM_INTFLAG_CAP1 :Capture interrupt for channel (1)
|
||||
* - MCPWM_INTFLAG_LIM2 :Limit interrupt for channel (2)
|
||||
* - MCPWM_INTFLAG_MAT2 :Match interrupt for channel (2)
|
||||
* - MCPWM_INTFLAG_CAP2 :Capture interrupt for channel (2)
|
||||
* - MCPWM_INTFLAG_ABORT :Fast abort interrupt
|
||||
* @return None
|
||||
* Note: all these ulIntType values above can be ORed together for using as input parameter.
|
||||
**********************************************************************/
|
||||
void MCPWM_IntSet(LPC_MCPWM_Type *MCPWMx, uint32_t ulIntType)
|
||||
{
|
||||
MCPWMx->INTF_SET = ulIntType;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Clear the specified interrupt pending for MCPWM peripheral
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @param[in] ulIntType Interrupt type, should be:
|
||||
* - MCPWM_INTFLAG_LIM0 :Limit interrupt for channel (0)
|
||||
* - MCPWM_INTFLAG_MAT0 :Match interrupt for channel (0)
|
||||
* - MCPWM_INTFLAG_CAP0 :Capture interrupt for channel (0)
|
||||
* - MCPWM_INTFLAG_LIM1 :Limit interrupt for channel (1)
|
||||
* - MCPWM_INTFLAG_MAT1 :Match interrupt for channel (1)
|
||||
* - MCPWM_INTFLAG_CAP1 :Capture interrupt for channel (1)
|
||||
* - MCPWM_INTFLAG_LIM2 :Limit interrupt for channel (2)
|
||||
* - MCPWM_INTFLAG_MAT2 :Match interrupt for channel (2)
|
||||
* - MCPWM_INTFLAG_CAP2 :Capture interrupt for channel (2)
|
||||
* - MCPWM_INTFLAG_ABORT :Fast abort interrupt
|
||||
* @return None
|
||||
* Note: all these ulIntType values above can be ORed together for using as input parameter.
|
||||
**********************************************************************/
|
||||
void MCPWM_IntClear(LPC_MCPWM_Type *MCPWMx, uint32_t ulIntType)
|
||||
{
|
||||
MCPWMx->INTF_CLR = ulIntType;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Check whether if the specified interrupt in MCPWM is set or not
|
||||
* @param[in] MCPWMx Motor Control PWM peripheral selected, should be: LPC_MCPWM
|
||||
* @param[in] ulIntType Interrupt type, should be:
|
||||
* - MCPWM_INTFLAG_LIM0 :Limit interrupt for channel (0)
|
||||
* - MCPWM_INTFLAG_MAT0 :Match interrupt for channel (0)
|
||||
* - MCPWM_INTFLAG_CAP0 :Capture interrupt for channel (0)
|
||||
* - MCPWM_INTFLAG_LIM1 :Limit interrupt for channel (1)
|
||||
* - MCPWM_INTFLAG_MAT1 :Match interrupt for channel (1)
|
||||
* - MCPWM_INTFLAG_CAP1 :Capture interrupt for channel (1)
|
||||
* - MCPWM_INTFLAG_LIM2 :Limit interrupt for channel (2)
|
||||
* - MCPWM_INTFLAG_MAT2 :Match interrupt for channel (2)
|
||||
* - MCPWM_INTFLAG_CAP2 :Capture interrupt for channel (2)
|
||||
* - MCPWM_INTFLAG_ABORT :Fast abort interrupt
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
FlagStatus MCPWM_GetIntStatus(LPC_MCPWM_Type *MCPWMx, uint32_t ulIntType)
|
||||
{
|
||||
return ((MCPWMx->INTF & ulIntType) ? SET : RESET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _MCPWM */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_nvic.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_nvic.c
|
||||
* @brief Contains all expansion functions support for NVIC firmware
|
||||
* library on lpc43xx. The main NVIC functions are defined in
|
||||
* core_cm3.h
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup NVIC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_nvic.h"
|
||||
|
||||
|
||||
/* Private Macros ------------------------------------------------------------- */
|
||||
/** @addtogroup NVIC_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Vector table offset bit mask */
|
||||
#define NVIC_VTOR_MASK 0x3FFFFF80
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup NVIC_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*****************************************************************************//**
|
||||
* @brief Set Vector Table Offset value
|
||||
* @param offset Offset value
|
||||
* @return None
|
||||
*******************************************************************************/
|
||||
void NVIC_SetVTOR(uint32_t offset)
|
||||
{
|
||||
// SCB->VTOR = (offset & NVIC_VTOR_MASK);
|
||||
SCB->VTOR = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_pwr.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_pwr.c
|
||||
* @brief Contains all functions support for Power Control
|
||||
* firmware library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup PWR
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc_types.h"
|
||||
#include "lpc43xx_scu.h"
|
||||
#include "lpc43xx_pwr.h"
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enter Sleep mode with co-operated instruction by the Cortex-M3.
|
||||
* @param[in] None
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void PWR_Sleep(void)
|
||||
{
|
||||
//LPC_PMC->SLEEP0_MODE = 0x00;
|
||||
/* Sleep Mode*/
|
||||
__WFI();
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enter Deep Sleep mode with co-operated instruction by the Cortex-M3.
|
||||
* @param[in] None
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void PWR_DeepSleep(void)
|
||||
{
|
||||
/* Deep-Sleep Mode, set SLEEPDEEP bit */
|
||||
SCB->SCR = 0x4;
|
||||
LPC_PMC->PD0_SLEEP0_MODE = PWR_SLEEP_MODE_DEEP_SLEEP;
|
||||
/* Deep Sleep Mode*/
|
||||
__WFI();
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enter Power Down mode with co-operated instruction by the Cortex-M3.
|
||||
* @param[in] None
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void PWR_PowerDown(void)
|
||||
{
|
||||
/* Deep-Sleep Mode, set SLEEPDEEP bit */
|
||||
SCB->SCR = 0x4;
|
||||
LPC_PMC->PD0_SLEEP0_MODE = PWR_SLEEP_MODE_POWER_DOWN;
|
||||
/* Power Down Mode*/
|
||||
__WFI();
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enter Deep Power Down mode with co-operated instruction by the Cortex-M3.
|
||||
* @param[in] None
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void PWR_DeepPowerDown(void)
|
||||
{
|
||||
/* Deep-Sleep Mode, set SLEEPDEEP bit */
|
||||
SCB->SCR = 0x4;
|
||||
LPC_PMC->PD0_SLEEP0_MODE = PWR_SLEEP_MODE_DEEP_POWER_DOWN;
|
||||
/* Deep Power Down Mode*/
|
||||
__WFI();
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,546 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_qei.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_pwr.c
|
||||
* @brief Contains all functions support for QEI firmware library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors�
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup QEI
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_qei.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
#ifdef _QEI
|
||||
|
||||
/* Private Types -------------------------------------------------------------- */
|
||||
/** @defgroup QEI_Private_Types QEI Private Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief QEI configuration union type definition
|
||||
*/
|
||||
typedef union {
|
||||
QEI_CFG_Type bmQEIConfig;
|
||||
uint32_t ulQEIConfig;
|
||||
} QEI_CFGOPT_Type;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
LPC_QEI_Type* QEI_GetPointer(uint8_t qeiId);
|
||||
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup QEI_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get the point to typedef of QEI component
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
LPC_QEI_Type* QEI_GetPointer(uint8_t qeiId)
|
||||
{
|
||||
LPC_QEI_Type* pQei = NULL;
|
||||
|
||||
if(qeiId == 0)
|
||||
{
|
||||
pQei = LPC_QEI;
|
||||
}
|
||||
|
||||
return pQei;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Resets value for each type of QEI value, such as velocity,
|
||||
* counter, position, etc..
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @param[in] ulResetType QEI Reset Type, should be one of the following:
|
||||
* - QEI_RESET_POS :Reset Position Counter
|
||||
* - QEI_RESET_POSOnIDX :Reset Position Counter on Index signal
|
||||
* - QEI_RESET_VEL :Reset Velocity
|
||||
* - QEI_RESET_IDX :Reset Index Counter
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void QEI_Reset(uint8_t qeiId, uint32_t ulResetType)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
pQei->CON = ulResetType;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Initializes the QEI peripheral according to the specified
|
||||
* parameters in the QEI_ConfigStruct.
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @param[in] QEI_ConfigStruct Pointer to a QEI_CFG_Type structure
|
||||
* that contains the configuration information for the
|
||||
* specified QEI peripheral
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void QEI_Init(uint8_t qeiId, QEI_CFG_Type *QEI_ConfigStruct)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
/* Set up clock and power for QEI module */
|
||||
// Already enabled by BASE_M3_CLK
|
||||
|
||||
// Reset all remaining value in QEI peripheral
|
||||
|
||||
pQei->MAXPOS = 0x00;
|
||||
pQei->CMPOS0 = 0x00;
|
||||
pQei->CMPOS1 = 0x00;
|
||||
pQei->CMPOS2 = 0x00;
|
||||
pQei->INXCMP0 = 0x00;
|
||||
pQei->VELCOMP = 0x00;
|
||||
|
||||
pQei->LOAD = 0x00;
|
||||
pQei->CON = QEI_CON_RESP | QEI_CON_RESV | QEI_CON_RESI;
|
||||
|
||||
pQei->FILTERPHA = 0x00;
|
||||
pQei->FILTERPHB = 0x00;
|
||||
pQei->FILTERINX = 0x00;
|
||||
|
||||
// Disable all Interrupt
|
||||
pQei->IEC = QEI_IECLR_BITMASK;
|
||||
|
||||
// Clear all Interrupt pending
|
||||
pQei->CLR = QEI_INTCLR_BITMASK;
|
||||
|
||||
// Set QEI configuration value corresponding to its setting up value
|
||||
pQei->CONF = ((QEI_CFGOPT_Type *)QEI_ConfigStruct)->ulQEIConfig;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief De-Initalize QEI peripheral
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void QEI_DeInit(uint8_t qeiId)
|
||||
{
|
||||
/* Turn off clock and power for QEI module */
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************//**
|
||||
* @brief Fills each QIE_InitStruct member with its default value:
|
||||
* - DirectionInvert = QEI_DIRINV_NONE
|
||||
* - SignalMode = QEI_SIGNALMODE_QUAD
|
||||
* - CaptureMode = QEI_CAPMODE_4X
|
||||
* - InvertIndex = QEI_INVINX_NONE
|
||||
* @param[in] QIE_InitStruct Pointer to a QEI_CFG_Type structure which will be
|
||||
* initialized.
|
||||
* @return None
|
||||
*******************************************************************************/
|
||||
void QEI_GetCfgDefault(QEI_CFG_Type *QIE_InitStruct)
|
||||
{
|
||||
QIE_InitStruct->CaptureMode = QEI_CAPMODE_4X;
|
||||
QIE_InitStruct->DirectionInvert = QEI_DIRINV_NONE;
|
||||
QIE_InitStruct->InvertIndex = QEI_INVINX_NONE;
|
||||
QIE_InitStruct->SignalMode = QEI_SIGNALMODE_QUAD;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Check whether if specified flag status is set or not
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @param[in] ulFlagType Status Flag Type, should be one of the following:
|
||||
* - QEI_STATUS_DIR: Direction Status
|
||||
* @return New Status of this status flag (SET or RESET)
|
||||
**********************************************************************/
|
||||
FlagStatus QEI_GetStatus(uint8_t qeiId, uint32_t ulFlagType)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
return ((pQei->STAT & ulFlagType) ? SET : RESET);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get current position value in QEI peripheral
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @return Current position value of QEI peripheral
|
||||
**********************************************************************/
|
||||
uint32_t QEI_GetPosition(uint8_t qeiId)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
return (pQei->POS);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set max position value for QEI peripheral
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @param[in] ulMaxPos Max position value to set
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void QEI_SetMaxPosition(uint8_t qeiId, uint32_t ulMaxPos)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
pQei->MAXPOS = ulMaxPos;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set position compare value for QEI peripheral
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @param[in] bPosCompCh Compare Position channel, should be:
|
||||
* - QEI_COMPPOS_CH_0 :QEI compare position channel 0
|
||||
* - QEI_COMPPOS_CH_1 :QEI compare position channel 1
|
||||
* - QEI_COMPPOS_CH_2 :QEI compare position channel 2
|
||||
* @param[in] ulPosComp Compare Position value to set
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void QEI_SetPositionComp(uint8_t qeiId, uint8_t bPosCompCh, uint32_t ulPosComp)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
uint32_t *tmp;
|
||||
|
||||
tmp = (uint32_t *) (&(pQei->CMPOS0) + bPosCompCh * 4);
|
||||
*tmp = ulPosComp;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get current index counter of QEI peripheral
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @return Current value of QEI index counter
|
||||
**********************************************************************/
|
||||
uint32_t QEI_GetIndex(uint8_t qeiId)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
return (pQei->INXCNT);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set value for index compare in QEI peripheral
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @param[in] ulIndexComp Compare Index Value to set
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void QEI_SetIndexComp(uint8_t qeiId, uint32_t ulIndexComp)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
pQei->INXCMP0 = ulIndexComp;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set timer reload value for QEI peripheral. When the velocity timer is
|
||||
* over-flow, the value that set for Timer Reload register will be loaded
|
||||
* into the velocity timer for next period. The calculated velocity in RPM
|
||||
* therefore will be affect by this value.
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @param[in] QEIReloadStruct QEI reload structure
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void QEI_SetTimerReload(uint8_t qeiId, QEI_RELOADCFG_Type *QEIReloadStruct)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
uint64_t pclk;
|
||||
|
||||
if (QEIReloadStruct->ReloadOption == QEI_TIMERRELOAD_TICKVAL)
|
||||
{
|
||||
pQei->LOAD = QEIReloadStruct->ReloadValue - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 1
|
||||
// pclk = CGU_GetPCLKFrequency(CGU_PERIPHERAL_M3CORE);
|
||||
pclk = CGU_GetPCLKFrequency(CGU_PERIPHERAL_M4CORE);
|
||||
|
||||
pclk = (pclk /(1000000/QEIReloadStruct->ReloadValue)) - 1;
|
||||
|
||||
pQei->LOAD = (uint32_t)pclk;
|
||||
#else
|
||||
ld = M3Frequency;
|
||||
|
||||
if (ld/1000000 > 0)
|
||||
{
|
||||
ld /= 1000000;
|
||||
ld *= QEIReloadStruct->ReloadValue;
|
||||
ld -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ld *= QEIReloadStruct->ReloadValue;
|
||||
ld /= 1000000;
|
||||
ld -= 1;
|
||||
}
|
||||
|
||||
pQei->LOAD = ld;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get current timer counter in QEI peripheral
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @return Current timer counter in QEI peripheral
|
||||
**********************************************************************/
|
||||
uint32_t QEI_GetTimer(uint8_t qeiId)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
return (pQei->TIME);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get current velocity pulse counter in current time period
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @return Current velocity pulse counter value
|
||||
**********************************************************************/
|
||||
uint32_t QEI_GetVelocity(uint8_t qeiId)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
return (pQei->VEL);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get the most recently measured velocity of the QEI. When
|
||||
* the Velocity timer in QEI is over-flow, the current velocity
|
||||
* value will be loaded into Velocity Capture register.
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @return The most recently measured velocity value
|
||||
**********************************************************************/
|
||||
uint32_t QEI_GetVelocityCap(uint8_t qeiId)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
return (pQei->CAP);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set Velocity Compare value for QEI peripheral
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @param[in] ulVelComp Compare Velocity value to set
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void QEI_SetVelocityComp(uint8_t qeiId, uint32_t ulVelComp)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
pQei->VELCOMP = ulVelComp;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set value of sampling count for the digital filter in
|
||||
* QEI peripheral
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @param[in] ulSamplingPulse Value of sampling count to set
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void QEI_SetDigiFilter(uint8_t qeiId, st_Qei_FilterCfg FilterVal)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
pQei->FILTERPHA = FilterVal.PHA_FilterVal;
|
||||
pQei->FILTERPHB = FilterVal.PHB_FilterVal;
|
||||
pQei->FILTERINX = FilterVal.INX_FilterVal;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Check whether if specified interrupt flag status in QEI
|
||||
* peripheral is set or not
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @param[in] ulIntType Interrupt Flag Status type, should be:
|
||||
* - QEI_INTFLAG_INX_Int : index pulse was detected interrupt
|
||||
* - QEI_INTFLAG_TIM_Int : Velocity timer over flow interrupt
|
||||
* - QEI_INTFLAG_VELC_Int : Capture velocity is less than compare interrupt
|
||||
* - QEI_INTFLAG_DIR_Int : Change of direction interrupt
|
||||
* - QEI_INTFLAG_ERR_Int : An encoder phase error interrupt
|
||||
* - QEI_INTFLAG_ENCLK_Int : An encoder clock pulse was detected interrupt
|
||||
* - QEI_INTFLAG_POS0_Int : position 0 compare value is equal to the current position interrupt
|
||||
* - QEI_INTFLAG_POS1_Int : position 1 compare value is equal to the current position interrupt
|
||||
* - QEI_INTFLAG_POS2_Int : position 2 compare value is equal to the current position interrupt
|
||||
* - QEI_INTFLAG_REV_Int : Index compare value is equal to the current index count interrupt
|
||||
* - QEI_INTFLAG_POS0REV_Int : Combined position 0 and revolution count interrupt
|
||||
* - QEI_INTFLAG_POS1REV_Int : Combined position 1 and revolution count interrupt
|
||||
* - QEI_INTFLAG_POS2REV_Int : Combined position 2 and revolution count interrupt
|
||||
* @return New State of specified interrupt flag status (SET or RESET)
|
||||
**********************************************************************/
|
||||
FlagStatus QEI_GetIntStatus(uint8_t qeiId, uint32_t ulIntType)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
return((pQei->INTSTAT & ulIntType) ? SET : RESET);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable/Disable specified interrupt in QEI peripheral
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @param[in] ulIntType Interrupt Flag Status type, should be:
|
||||
* - QEI_INTFLAG_INX_Int : index pulse was detected interrupt
|
||||
* - QEI_INTFLAG_TIM_Int : Velocity timer over flow interrupt
|
||||
* - QEI_INTFLAG_VELC_Int : Capture velocity is less than compare interrupt
|
||||
* - QEI_INTFLAG_DIR_Int : Change of direction interrupt
|
||||
* - QEI_INTFLAG_ERR_Int : An encoder phase error interrupt
|
||||
* - QEI_INTFLAG_ENCLK_Int : An encoder clock pulse was detected interrupt
|
||||
* - QEI_INTFLAG_POS0_Int : position 0 compare value is equal to the current position interrupt
|
||||
* - QEI_INTFLAG_POS1_Int : position 1 compare value is equal to the current position interrupt
|
||||
* - QEI_INTFLAG_POS2_Int : position 2 compare value is equal to the current position interrupt
|
||||
* - QEI_INTFLAG_REV_Int : Index compare value is equal to the current index count interrupt
|
||||
* - QEI_INTFLAG_POS0REV_Int : Combined position 0 and revolution count interrupt
|
||||
* - QEI_INTFLAG_POS1REV_Int : Combined position 1 and revolution count interrupt
|
||||
* - QEI_INTFLAG_POS2REV_Int : Combined position 2 and revolution count interrupt
|
||||
* @param[in] NewState New function state, should be:
|
||||
* - DISABLE
|
||||
* - ENABLE
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void QEI_IntCmd(uint8_t qeiId, uint32_t ulIntType, FunctionalState NewState)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
if (NewState == ENABLE)
|
||||
{
|
||||
pQei->IES = ulIntType;
|
||||
}
|
||||
else
|
||||
{
|
||||
pQei->IEC = ulIntType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Sets (forces) specified interrupt in QEI peripheral
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @param[in] ulIntType Interrupt Flag Status type, should be:
|
||||
* - QEI_INTFLAG_INX_Int : index pulse was detected interrupt
|
||||
* - QEI_INTFLAG_TIM_Int : Velocity timer over flow interrupt
|
||||
* - QEI_INTFLAG_VELC_Int : Capture velocity is less than compare interrupt
|
||||
* - QEI_INTFLAG_DIR_Int : Change of direction interrupt
|
||||
* - QEI_INTFLAG_ERR_Int : An encoder phase error interrupt
|
||||
* - QEI_INTFLAG_ENCLK_Int : An encoder clock pulse was detected interrupt
|
||||
* - QEI_INTFLAG_POS0_Int : position 0 compare value is equal to the current position interrupt
|
||||
* - QEI_INTFLAG_POS1_Int : position 1 compare value is equal to the current position interrupt
|
||||
* - QEI_INTFLAG_POS2_Int : position 2 compare value is equal to the current position interrupt
|
||||
* - QEI_INTFLAG_REV_Int : Index compare value is equal to the current index count interrupt
|
||||
* - QEI_INTFLAG_POS0REV_Int : Combined position 0 and revolution count interrupt
|
||||
* - QEI_INTFLAG_POS1REV_Int : Combined position 1 and revolution count interrupt
|
||||
* - QEI_INTFLAG_POS2REV_Int : Combined position 2 and revolution count interrupt
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void QEI_IntSet(uint8_t qeiId, uint32_t ulIntType)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
pQei->SET = ulIntType;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Clear (force) specified interrupt (pending) in QEI peripheral
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @param[in] ulIntType Interrupt Flag Status type, should be:
|
||||
* - QEI_INTFLAG_INX_Int : index pulse was detected interrupt
|
||||
* - QEI_INTFLAG_TIM_Int : Velocity timer over flow interrupt
|
||||
* - QEI_INTFLAG_VELC_Int : Capture velocity is less than compare interrupt
|
||||
* - QEI_INTFLAG_DIR_Int : Change of direction interrupt
|
||||
* - QEI_INTFLAG_ERR_Int : An encoder phase error interrupt
|
||||
* - QEI_INTFLAG_ENCLK_Int : An encoder clock pulse was detected interrupt
|
||||
* - QEI_INTFLAG_POS0_Int : position 0 compare value is equal to the current position interrupt
|
||||
* - QEI_INTFLAG_POS1_Int : position 1 compare value is equal to the current position interrupt
|
||||
* - QEI_INTFLAG_POS2_Int : position 2 compare value is equal to the current position interrupt
|
||||
* - QEI_INTFLAG_REV_Int : Index compare value is equal to the current index count interrupt
|
||||
* - QEI_INTFLAG_POS0REV_Int : Combined position 0 and revolution count interrupt
|
||||
* - QEI_INTFLAG_POS1REV_Int : Combined position 1 and revolution count interrupt
|
||||
* - QEI_INTFLAG_POS2REV_Int : Combined position 2 and revolution count interrupt
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void QEI_IntClear(uint8_t qeiId, uint32_t ulIntType)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
pQei->CLR = ulIntType;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Calculates the actual velocity in RPM passed via velocity
|
||||
* capture value and Pulse Per Round (of the encoder) value
|
||||
* parameter input.
|
||||
* @param[in] qeiId The Id of the expected QEI component, should be: 0
|
||||
* @param[in] ulVelCapValue Velocity capture input value that can be
|
||||
* got from QEI_GetVelocityCap() function
|
||||
* @param[in] ulPPR Pulse per round of encoder
|
||||
* @return The actual value of velocity in RPM (Round per minute)
|
||||
**********************************************************************/
|
||||
uint32_t QEI_CalculateRPM(uint8_t qeiId, uint32_t ulVelCapValue, uint32_t ulPPR)
|
||||
{
|
||||
LPC_QEI_Type* pQei = QEI_GetPointer(qeiId);
|
||||
|
||||
uint64_t rpm, clock, Load, edges;
|
||||
|
||||
// Get current Clock rate for timer input
|
||||
// clock = CGU_GetPCLKFrequency(CGU_PERIPHERAL_M3CORE);
|
||||
clock = CGU_GetPCLKFrequency(CGU_PERIPHERAL_M4CORE);
|
||||
// Get Timer load value (velocity capture period)
|
||||
Load = (uint64_t)(pQei->LOAD + 1);
|
||||
|
||||
// Get Edge
|
||||
edges = (uint64_t)((pQei->CONF & QEI_CONF_CAPMODE) ? 4 : 2);
|
||||
|
||||
// Calculate RPM
|
||||
rpm = ((clock * ulVelCapValue * 60) / (Load * ulPPR * edges));
|
||||
|
||||
return (uint32_t)(rpm);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _QEI */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* --------------------------------- End Of File ------------------------------ */
|
||||
@@ -0,0 +1,258 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_rgu.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_rgu.c
|
||||
* @brief Contains all functions support for RGU firmware library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup RGU
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_rgu.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
|
||||
#ifdef _RGU
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup RGU_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Soft Reset a Signal
|
||||
* @param[in] ResetSignal indicates which signal will be reset, should be:
|
||||
* - RGU_SIG_CORE :Core
|
||||
* - RGU_SIG_PERIPH :Peripheral
|
||||
* - RGU_SIG_MASTER :Master
|
||||
* - RGU_SIG_WWDT :WWDT
|
||||
* - RGU_SIG_CREG :Configuration register block
|
||||
* - RGU_SIG_BUS :Buses
|
||||
* - RGU_SIG_SCU :System control unit
|
||||
* - RGU_SIG_PINMUX :Pin mux
|
||||
* - RGU_SIG_M3 :Cortex-M3 system
|
||||
* - RGU_SIG_LCD :LCD controller
|
||||
* - RGU_SIG_USB0 :USB0
|
||||
* - RGU_SIG_USB1 :USB1
|
||||
* - RGU_SIG_DMA :DMA
|
||||
* - RGU_SIG_SDIO :SDIO
|
||||
* - RGU_SIG_EMC :External memory controller
|
||||
* - RGU_SIG_ETHERNET :Ethernet
|
||||
* - RGU_SIG_AES :AES
|
||||
* - RGU_SIG_GPIO :GPIO
|
||||
* - RGU_SIG_TIMER0 :Timer 0
|
||||
* - RGU_SIG_TIMER1 :Timer 1
|
||||
* - RGU_SIG_TIMER2 :Timer 2
|
||||
* - RGU_SIG_TIMER3 :Timer 3
|
||||
* - RGU_SIG_RITIMER :Repetitive Interrupt Timer
|
||||
* - RGU_SIG_SCT :State Configurable Timer
|
||||
* - RGU_SIG_MOTOCONPWM:Motor Control PWM
|
||||
* - RGU_SIG_QEI :QEI
|
||||
* - RGU_SIG_ADC0 :ADC0
|
||||
* - RGU_SIG_ADC1 :ADC1
|
||||
* - RGU_SIG_DAC :DAC
|
||||
* - RGU_SIG_UART0 :UART0
|
||||
* - RGU_SIG_UART1 :UART1
|
||||
* - RGU_SIG_UART2 :UART2
|
||||
* - RGU_SIG_UART3 :UART3
|
||||
* - RGU_SIG_I2C0 :I2C0
|
||||
* - RGU_SIG_I2C1 :I2C1
|
||||
* - RGU_SIG_SSP0 :SSP0
|
||||
* - RGU_SIG_SSP1 :SSP1
|
||||
* - RGU_SIG_I2S :I2S
|
||||
* - RGU_SIG_SPIFI :SPIFI
|
||||
* - RGU_SIG_CAN :CAN
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RGU_SoftReset(RGU_SIG ResetSignal)
|
||||
{
|
||||
if(ResetSignal < 32){
|
||||
LPC_RGU->RESET_CTRL0 = 1 << ResetSignal;
|
||||
LPC_RGU->RESET_CTRL0 = 0;
|
||||
}else{
|
||||
LPC_RGU->RESET_CTRL1 = 1 << (ResetSignal - 32);
|
||||
LPC_RGU->RESET_CTRL1 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get source cause of a signal
|
||||
* @param[in] ResetSignal reset signal, should be:
|
||||
* - RGU_SIG_CORE :Core
|
||||
* - RGU_SIG_PERIPH :Peripheral
|
||||
* - RGU_SIG_MASTER :Master
|
||||
* - RGU_SIG_WWDT :WWDT
|
||||
* - RGU_SIG_CREG :Configuration register block
|
||||
* - RGU_SIG_BUS :Buses
|
||||
* - RGU_SIG_SCU :System control unit
|
||||
* - RGU_SIG_PINMUX :Pin mux
|
||||
* - RGU_SIG_M3 :Cortex-M3 system
|
||||
* - RGU_SIG_LCD :LCD controller
|
||||
* - RGU_SIG_USB0 :USB0
|
||||
* - RGU_SIG_USB1 :USB1
|
||||
* - RGU_SIG_DMA :DMA
|
||||
* - RGU_SIG_SDIO :SDIO
|
||||
* - RGU_SIG_EMC :External memory controller
|
||||
* - RGU_SIG_ETHERNET :Ethernet
|
||||
* - RGU_SIG_AES :AES
|
||||
* - RGU_SIG_GPIO :GPIO
|
||||
* - RGU_SIG_TIMER0 :Timer 0
|
||||
* - RGU_SIG_TIMER1 :Timer 1
|
||||
* - RGU_SIG_TIMER2 :Timer 2
|
||||
* - RGU_SIG_TIMER3 :Timer 3
|
||||
* - RGU_SIG_RITIMER :Repetitive Interrupt Timer
|
||||
* - RGU_SIG_SCT :State Configurable Timer
|
||||
* - RGU_SIG_MOTOCONPWM:Motor Control PWM
|
||||
* - RGU_SIG_QEI :QEI
|
||||
* - RGU_SIG_ADC0 :ADC0
|
||||
* - RGU_SIG_ADC1 :ADC1
|
||||
* - RGU_SIG_DAC :DAC
|
||||
* - RGU_SIG_UART0 :UART0
|
||||
* - RGU_SIG_UART1 :UART1
|
||||
* - RGU_SIG_UART2 :UART2
|
||||
* - RGU_SIG_UART3 :UART3
|
||||
* - RGU_SIG_I2C0 :I2C0
|
||||
* - RGU_SIG_I2C1 :I2C1
|
||||
* - RGU_SIG_SSP0 :SSP0
|
||||
* - RGU_SIG_SSP1 :SSP1
|
||||
* - RGU_SIG_I2S :I2S
|
||||
* - RGU_SIG_SPIFI :SPIFI
|
||||
* - RGU_SIG_CAN :CAN
|
||||
* @return Source cause of reset, could be:
|
||||
* - RGU_SRC_NONE :No source
|
||||
* - RGU_SRC_SOFT :Software reset source
|
||||
* - RGU_SRC_EXT :External reset source
|
||||
* - RGU_SRC_CORE :Core reset source
|
||||
* - RGU_SRC_PERIPH :Peripheral reset source
|
||||
* - RGU_SRC_MASTER :Master reset source
|
||||
* - RGU_SRC_BOD :BOD reset source
|
||||
* - RGU_SRC_WWDT :WWDT reset source
|
||||
**********************************************************************/
|
||||
RGU_SRC RGU_GetSource(RGU_SIG ResetSignal)
|
||||
{
|
||||
uint32_t i, temp, registercache;
|
||||
if(ResetSignal < 16)
|
||||
temp = 3 & (LPC_RGU->RESET_STATUS0 >> ResetSignal);
|
||||
else if(ResetSignal < 32)
|
||||
temp = 3 & (LPC_RGU->RESET_STATUS1 >> (ResetSignal - 16));
|
||||
else if(ResetSignal < 48)
|
||||
temp = 3 & (LPC_RGU->RESET_STATUS2 >> (ResetSignal - 32));
|
||||
else
|
||||
temp = 3 & (LPC_RGU->RESET_STATUS3 >> (ResetSignal - 48));
|
||||
|
||||
if(temp == 0) return RGU_SRC_NONE;
|
||||
else if(temp == 3) return RGU_SRC_SOFT;
|
||||
else if(temp == 1){
|
||||
registercache = (((uint32_t*)&LPC_RGU->RESET_EXT_STAT0)[ResetSignal]);
|
||||
for(i = 0; i < 6; i++){
|
||||
if(registercache & (1<<i)){
|
||||
return (RGU_SRC)(RGU_SRC_EXT + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return RGU_SRC_NONE;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get Current Status of Signal
|
||||
* @param[in] ResetSignal Reset Signal, should be:
|
||||
* - RGU_SIG_CORE :Core
|
||||
* - RGU_SIG_PERIPH :Peripheral
|
||||
* - RGU_SIG_MASTER :Master
|
||||
* - RGU_SIG_WWDT :WWDT
|
||||
* - RGU_SIG_CREG :Configuration register block
|
||||
* - RGU_SIG_BUS :Buses
|
||||
* - RGU_SIG_SCU :System control unit
|
||||
* - RGU_SIG_PINMUX :Pin mux
|
||||
* - RGU_SIG_M3 :Cortex-M3 system
|
||||
* - RGU_SIG_LCD :LCD controller
|
||||
* - RGU_SIG_USB0 :USB0
|
||||
* - RGU_SIG_USB1 :USB1
|
||||
* - RGU_SIG_DMA :DMA
|
||||
* - RGU_SIG_SDIO :SDIO
|
||||
* - RGU_SIG_EMC :External memory controller
|
||||
* - RGU_SIG_ETHERNET :Ethernet
|
||||
* - RGU_SIG_AES :AES
|
||||
* - RGU_SIG_GPIO :GPIO
|
||||
* - RGU_SIG_TIMER0 :Timer 0
|
||||
* - RGU_SIG_TIMER1 :Timer 1
|
||||
* - RGU_SIG_TIMER2 :Timer 2
|
||||
* - RGU_SIG_TIMER3 :Timer 3
|
||||
* - RGU_SIG_RITIMER :Repetitive Interrupt Timer
|
||||
* - RGU_SIG_SCT :State Configurable Timer
|
||||
* - RGU_SIG_MOTOCONPWM:Motor Control PWM
|
||||
* - RGU_SIG_QEI :QEI
|
||||
* - RGU_SIG_ADC0 :ADC0
|
||||
* - RGU_SIG_ADC1 :ADC1
|
||||
* - RGU_SIG_DAC :DAC
|
||||
* - RGU_SIG_UART0 :UART0
|
||||
* - RGU_SIG_UART1 :UART1
|
||||
* - RGU_SIG_UART2 :UART2
|
||||
* - RGU_SIG_UART3 :UART3
|
||||
* - RGU_SIG_I2C0 :I2C0
|
||||
* - RGU_SIG_I2C1 :I2C1
|
||||
* - RGU_SIG_SSP0 :SSP0
|
||||
* - RGU_SIG_SSP1 :SSP1
|
||||
* - RGU_SIG_I2S :I2S
|
||||
* - RGU_SIG_SPIFI :SPIFI
|
||||
* - RGU_SIG_CAN :CAN
|
||||
* @return Signal status, could be:
|
||||
* - TRUE :reset is active
|
||||
* - FALSE :reset is inactive
|
||||
**********************************************************************/
|
||||
Bool RGU_GetSignalStatus(RGU_SIG ResetSignal)
|
||||
{
|
||||
if(ResetSignal < 32)
|
||||
return (Bool)!(LPC_RGU->RESET_ACTIVE_STATUS0 | (1 << ResetSignal));
|
||||
else
|
||||
return (Bool)!(LPC_RGU->RESET_ACTIVE_STATUS1 | (1 << (ResetSignal - 32)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _RGU */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* --------------------------------- End Of File ------------------------------ */
|
||||
@@ -0,0 +1,201 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_rit.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_rit.c
|
||||
* @brief Contains all functions support for RIT firmware library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup RIT
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_rit.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
#ifdef _RIT
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup RIT_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/******************************************************************************//*
|
||||
* @brief Initial for RIT
|
||||
* - Turn on power and clock
|
||||
* - Setup default register values
|
||||
* @param[in] RITx is RIT peripheral selected, should be: LPC_RIT
|
||||
* @return None
|
||||
*******************************************************************************/
|
||||
void RIT_Init(LPC_RITIMER_Type *RITx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RITx(RITx));
|
||||
//CGU_ConfigPPWR (CGU_PCONP_PCRIT, ENABLE);
|
||||
//Set up default register values
|
||||
RITx->COMPVAL = 0xFFFFFFFF;
|
||||
RITx->MASK = 0x00000000;
|
||||
RITx->CTRL = 0x0C;
|
||||
RITx->COUNTER = 0x00000000;
|
||||
// Turn on power and clock
|
||||
|
||||
}
|
||||
/******************************************************************************//*
|
||||
* @brief DeInitial for RIT
|
||||
* - Turn off power and clock
|
||||
* - ReSetup default register values
|
||||
* @param[in] RITx is RIT peripheral selected, should be: LPC_RIT
|
||||
* @return None
|
||||
*******************************************************************************/
|
||||
void RIT_DeInit(LPC_RITIMER_Type *RITx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RITx(RITx));
|
||||
|
||||
// Turn off power and clock
|
||||
//CGU_ConfigPPWR (CGU_PCONP_PCRIT, DISABLE);
|
||||
//ReSetup default register values
|
||||
RITx->COMPVAL = 0xFFFFFFFF;
|
||||
RITx->MASK = 0x00000000;
|
||||
RITx->CTRL = 0x0C;
|
||||
RITx->COUNTER = 0x00000000;
|
||||
}
|
||||
|
||||
/******************************************************************************//*
|
||||
* @brief Set compare value, mask value and time counter value
|
||||
* @param[in] RITx is RIT peripheral selected, should be: LPC_RIT
|
||||
* @param[in] time_interval timer interval value (ms)
|
||||
* @return None
|
||||
*******************************************************************************/
|
||||
|
||||
void RIT_TimerConfig(LPC_RITIMER_Type *RITx, uint32_t time_interval)
|
||||
{
|
||||
uint32_t clock_rate, cmp_value;
|
||||
CHECK_PARAM(PARAM_RITx(RITx));
|
||||
|
||||
// Get PCLK value of RIT
|
||||
clock_rate = /*CGU_GetPCLK(CGU_PCLKSEL_RIT)*/ CGU_GetPCLKFrequency(CGU_PERIPHERAL_M4CORE);
|
||||
|
||||
/* calculate compare value for RIT to generate interrupt at
|
||||
* specified time interval
|
||||
* COMPVAL = (RIT_PCLK * time_interval)/1000
|
||||
* (with time_interval unit is millisecond)
|
||||
*/
|
||||
cmp_value = (clock_rate /1000) * time_interval;
|
||||
RITx->COMPVAL = cmp_value;
|
||||
|
||||
/* Set timer enable clear bit to clear timer to 0 whenever
|
||||
* counter value equals the contents of RICOMPVAL
|
||||
*/
|
||||
RITx->CTRL |= (1<<1);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************//*
|
||||
* @brief Enable/Disable Timer
|
||||
* @param[in] RITx is RIT peripheral selected, should be: LPC_RIT
|
||||
* @param[in] NewState New State of this function
|
||||
* -ENABLE :Enable Timer
|
||||
* -DISABLE :Disable Timer
|
||||
* @return None
|
||||
*******************************************************************************/
|
||||
void RIT_Cmd(LPC_RITIMER_Type *RITx, FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RITx(RITx));
|
||||
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
|
||||
|
||||
//Enable or Disable Timer
|
||||
if(NewState==ENABLE)
|
||||
{
|
||||
RITx->CTRL |= RIT_CTRL_TEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
RITx->CTRL &= ~RIT_CTRL_TEN;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************//*
|
||||
* @brief Timer Enable/Disable on debug
|
||||
* @param[in] RITx is RIT peripheral selected, should be: LPC_RIT
|
||||
* @param[in] NewState New State of this function
|
||||
* -ENABLE :The timer is halted whenever a hardware break condition occurs
|
||||
* -DISABLE :Hardware break has no effect on the timer operation
|
||||
* @return None
|
||||
*******************************************************************************/
|
||||
void RIT_TimerDebugCmd(LPC_RITIMER_Type *RITx, FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RITx(RITx));
|
||||
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
|
||||
|
||||
//Timer Enable/Disable on break
|
||||
if(NewState==ENABLE)
|
||||
{
|
||||
RITx->CTRL |= RIT_CTRL_ENBR;
|
||||
}
|
||||
else
|
||||
{
|
||||
RITx->CTRL &= ~RIT_CTRL_ENBR;
|
||||
}
|
||||
}
|
||||
/******************************************************************************//*
|
||||
* @brief Check whether interrupt flag is set or not
|
||||
* @param[in] RITx is RIT peripheral selected, should be: LPC_RIT
|
||||
* @return Current interrupt status, could be
|
||||
* - SET
|
||||
* - RESET
|
||||
*******************************************************************************/
|
||||
IntStatus RIT_GetIntStatus(LPC_RITIMER_Type *RITx)
|
||||
{
|
||||
uint8_t result;
|
||||
CHECK_PARAM(PARAM_RITx(RITx));
|
||||
if((RITx->CTRL&RIT_CTRL_INTEN)==1) result= SET;
|
||||
else return RESET;
|
||||
//clear interrupt flag
|
||||
RITx->CTRL |= RIT_CTRL_INTEN;
|
||||
return (IntStatus)result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _RIT */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,765 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_rtc.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_rtc.c
|
||||
* @brief Contains all functions support for RTC firmware library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup RTC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_rtc.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
|
||||
#ifdef _RTC
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup RTC_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Initializes the RTC peripheral.
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @return None
|
||||
*********************************************************************/
|
||||
void RTC_Init (LPC_RTC_Type *RTCx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
|
||||
// Configure clock to RTC
|
||||
LPC_CREG->CREG0 &= ~((1<<3)|(1<<2)); // Reset 32Khz oscillator
|
||||
LPC_CREG->CREG0 |= (1<<1)|(1<<0); // Enable 32 kHz & 1 kHz on osc32k and release reset
|
||||
LPC_SCU->SFSCLK_0 = 1 | (0x3<<2); // function 1; CGU clk out, pull down
|
||||
LPC_CGU->BASE_OUT_CLK = (CGU_CLKSRC_32KHZ_OSC<<24) |(1<<11); // base clock out use 32KHz crystal and auto block
|
||||
do
|
||||
{
|
||||
/* Reset RTC clock*/
|
||||
RTCx->CCR = RTC_CCR_CTCRST | RTC_CCR_CCALEN;
|
||||
}
|
||||
while(RTCx->CCR!=(RTC_CCR_CTCRST | RTC_CCR_CCALEN));
|
||||
do
|
||||
{
|
||||
/* Finish resetting RTC clock*/
|
||||
RTCx->CCR = RTC_CCR_CCALEN;
|
||||
}
|
||||
while(RTCx->CCR != RTC_CCR_CCALEN);
|
||||
/* Clear counter increment and alarm interrupt */
|
||||
RTCx->ILR = RTC_IRL_RTCCIF | RTC_IRL_RTCALF;
|
||||
while(RTCx->ILR!=0);
|
||||
// Clear all register to be default
|
||||
RTCx->CIIR = 0x00;
|
||||
RTCx->AMR = 0xFF;
|
||||
RTCx->CALIBRATION = 0x00;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief De-initializes the RTC peripheral registers to their
|
||||
* default reset values.
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RTC_DeInit(LPC_RTC_Type *RTCx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
|
||||
RTCx->CCR = 0x00;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Reset clock tick counter in RTC peripheral
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RTC_ResetClockTickCounter(LPC_RTC_Type *RTCx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
|
||||
RTCx->CCR |= RTC_CCR_CTCRST;
|
||||
RTCx->CCR &= (~RTC_CCR_CTCRST) & RTC_CCR_BITMASK;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Start/Stop RTC peripheral
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] NewState New State of this function, should be:
|
||||
* - ENABLE :The time counters are enabled
|
||||
* - DISABLE :The time counters are disabled
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RTC_Cmd (LPC_RTC_Type *RTCx, FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
|
||||
|
||||
if (NewState == ENABLE)
|
||||
{
|
||||
do
|
||||
{
|
||||
RTCx->CCR |= RTC_CCR_CLKEN;
|
||||
}
|
||||
while((RTCx->CCR&RTC_CCR_CLKEN)==0);
|
||||
}
|
||||
else
|
||||
{
|
||||
RTCx->CCR &= (~RTC_CCR_CLKEN) & RTC_CCR_BITMASK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable/Disable Counter increment interrupt for each time type
|
||||
* in RTC peripheral
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] CntIncrIntType: Counter Increment Interrupt type,
|
||||
* an increment of this type value below will generates
|
||||
* an interrupt, should be:
|
||||
* - RTC_TIMETYPE_SECOND
|
||||
* - RTC_TIMETYPE_MINUTE
|
||||
* - RTC_TIMETYPE_HOUR
|
||||
* - RTC_TIMETYPE_DAYOFWEEK
|
||||
* - RTC_TIMETYPE_DAYOFMONTH
|
||||
* - RTC_TIMETYPE_DAYOFYEAR
|
||||
* - RTC_TIMETYPE_MONTH
|
||||
* - RTC_TIMETYPE_YEAR
|
||||
* @param[in] NewState New State of this function, should be:
|
||||
* - ENABLE: Counter Increment interrupt for this time type are enabled
|
||||
* - DISABLE: Counter Increment interrupt for this time type are disabled
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RTC_CntIncrIntConfig (LPC_RTC_Type *RTCx, uint32_t CntIncrIntType, \
|
||||
FunctionalState NewState)
|
||||
{
|
||||
uint32_t tem;
|
||||
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
|
||||
CHECK_PARAM(PARAM_RTC_TIMETYPE(CntIncrIntType));
|
||||
|
||||
switch (CntIncrIntType)
|
||||
{
|
||||
case RTC_TIMETYPE_SECOND:
|
||||
tem = RTC_CIIR_IMSEC;
|
||||
break;
|
||||
case RTC_TIMETYPE_MINUTE:
|
||||
tem = RTC_CIIR_IMMIN;
|
||||
break;
|
||||
case RTC_TIMETYPE_HOUR:
|
||||
tem = RTC_CIIR_IMHOUR;
|
||||
break;
|
||||
case RTC_TIMETYPE_DAYOFWEEK:
|
||||
tem = RTC_CIIR_IMDOW;
|
||||
break;
|
||||
case RTC_TIMETYPE_DAYOFMONTH:
|
||||
tem = RTC_CIIR_IMDOM;
|
||||
break;
|
||||
case RTC_TIMETYPE_DAYOFYEAR:
|
||||
tem = RTC_CIIR_IMDOY;
|
||||
break;
|
||||
case RTC_TIMETYPE_MONTH:
|
||||
tem = RTC_CIIR_IMMON;
|
||||
break;
|
||||
case RTC_TIMETYPE_YEAR:
|
||||
tem = RTC_CIIR_IMYEAR;
|
||||
break;
|
||||
}
|
||||
if (NewState == ENABLE)
|
||||
{
|
||||
//do
|
||||
{
|
||||
RTCx->CIIR |= tem;
|
||||
}
|
||||
while((RTCx->CIIR & tem)== 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//do
|
||||
{
|
||||
RTCx->CIIR &= (~tem) & RTC_CIIR_BITMASK;
|
||||
}
|
||||
while(RTCx->CIIR & tem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable/Disable Alarm interrupt for each time type
|
||||
* in RTC peripheral
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] AlarmTimeType: Alarm Time Interrupt type,
|
||||
* an matching of this type value below with current time
|
||||
* in RTC will generates an interrupt, should be:
|
||||
* - RTC_TIMETYPE_SECOND
|
||||
* - RTC_TIMETYPE_MINUTE
|
||||
* - RTC_TIMETYPE_HOUR
|
||||
* - RTC_TIMETYPE_DAYOFWEEK
|
||||
* - RTC_TIMETYPE_DAYOFMONTH
|
||||
* - RTC_TIMETYPE_DAYOFYEAR
|
||||
* - RTC_TIMETYPE_MONTH
|
||||
* - RTC_TIMETYPE_YEAR
|
||||
* @param[in] NewState New State of this function, should be:
|
||||
* - ENABLE: Alarm interrupt for this time type are enabled
|
||||
* - DISABLE: Alarm interrupt for this time type are disabled
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RTC_AlarmIntConfig (LPC_RTC_Type *RTCx, uint32_t AlarmTimeType, \
|
||||
FunctionalState NewState)
|
||||
{
|
||||
uint32_t tem;
|
||||
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
|
||||
CHECK_PARAM(PARAM_RTC_TIMETYPE(AlarmTimeType));
|
||||
|
||||
switch (AlarmTimeType)
|
||||
{
|
||||
case RTC_TIMETYPE_SECOND:
|
||||
tem = (RTC_AMR_AMRSEC);
|
||||
break;
|
||||
case RTC_TIMETYPE_MINUTE:
|
||||
tem = (RTC_AMR_AMRMIN);
|
||||
break;
|
||||
case RTC_TIMETYPE_HOUR:
|
||||
tem = (RTC_AMR_AMRHOUR);
|
||||
break;
|
||||
case RTC_TIMETYPE_DAYOFWEEK:
|
||||
tem = (RTC_AMR_AMRDOW);
|
||||
break;
|
||||
case RTC_TIMETYPE_DAYOFMONTH:
|
||||
tem = (RTC_AMR_AMRDOM);
|
||||
break;
|
||||
case RTC_TIMETYPE_DAYOFYEAR:
|
||||
tem = (RTC_AMR_AMRDOY);
|
||||
break;
|
||||
case RTC_TIMETYPE_MONTH:
|
||||
tem = (RTC_AMR_AMRMON);
|
||||
break;
|
||||
case RTC_TIMETYPE_YEAR:
|
||||
tem = (RTC_AMR_AMRYEAR);
|
||||
break;
|
||||
}
|
||||
if (NewState == ENABLE)
|
||||
{
|
||||
//do
|
||||
{
|
||||
RTCx->AMR &= (~tem) & RTC_AMR_BITMASK;
|
||||
}
|
||||
while(RTCx->AMR & tem);
|
||||
}
|
||||
else
|
||||
{
|
||||
//do
|
||||
{
|
||||
RTCx->AMR |= (tem);
|
||||
}
|
||||
while((RTCx->AMR & tem)== 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set current time value for each time type in RTC peripheral
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] Timetype Time Type, should be:
|
||||
* - RTC_TIMETYPE_SECOND
|
||||
* - RTC_TIMETYPE_MINUTE
|
||||
* - RTC_TIMETYPE_HOUR
|
||||
* - RTC_TIMETYPE_DAYOFWEEK
|
||||
* - RTC_TIMETYPE_DAYOFMONTH
|
||||
* - RTC_TIMETYPE_DAYOFYEAR
|
||||
* - RTC_TIMETYPE_MONTH
|
||||
* - RTC_TIMETYPE_YEAR
|
||||
* @param[in] TimeValue Time value to set
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RTC_SetTime (LPC_RTC_Type *RTCx, uint32_t Timetype, uint32_t TimeValue)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
CHECK_PARAM(PARAM_RTC_TIMETYPE(Timetype));
|
||||
|
||||
switch ( Timetype)
|
||||
{
|
||||
case RTC_TIMETYPE_SECOND:
|
||||
CHECK_PARAM(TimeValue <= RTC_SECOND_MAX);
|
||||
|
||||
RTCx->SEC = TimeValue & RTC_SEC_MASK;
|
||||
break;
|
||||
|
||||
case RTC_TIMETYPE_MINUTE:
|
||||
CHECK_PARAM(TimeValue <= RTC_MINUTE_MAX);
|
||||
|
||||
RTCx->MIN = TimeValue & RTC_MIN_MASK;
|
||||
break;
|
||||
|
||||
case RTC_TIMETYPE_HOUR:
|
||||
CHECK_PARAM(TimeValue <= RTC_HOUR_MAX);
|
||||
|
||||
RTCx->HRS = TimeValue & RTC_HOUR_MASK;
|
||||
break;
|
||||
|
||||
case RTC_TIMETYPE_DAYOFWEEK:
|
||||
CHECK_PARAM(TimeValue <= RTC_DAYOFWEEK_MAX);
|
||||
|
||||
RTCx->DOW = TimeValue & RTC_DOW_MASK;
|
||||
break;
|
||||
|
||||
case RTC_TIMETYPE_DAYOFMONTH:
|
||||
CHECK_PARAM((TimeValue <= RTC_DAYOFMONTH_MAX) \
|
||||
&& (TimeValue >= RTC_DAYOFMONTH_MIN));
|
||||
|
||||
RTCx->DOM = TimeValue & RTC_DOM_MASK;
|
||||
break;
|
||||
|
||||
case RTC_TIMETYPE_DAYOFYEAR:
|
||||
CHECK_PARAM((TimeValue >= RTC_DAYOFYEAR_MIN) \
|
||||
&& (TimeValue <= RTC_DAYOFYEAR_MAX));
|
||||
|
||||
RTCx->DOY = TimeValue & RTC_DOY_MASK;
|
||||
break;
|
||||
|
||||
case RTC_TIMETYPE_MONTH:
|
||||
CHECK_PARAM((TimeValue >= RTC_MONTH_MIN) \
|
||||
&& (TimeValue <= RTC_MONTH_MAX));
|
||||
|
||||
RTCx->MONTH = TimeValue & RTC_MONTH_MASK;
|
||||
break;
|
||||
|
||||
case RTC_TIMETYPE_YEAR:
|
||||
CHECK_PARAM(TimeValue <= RTC_YEAR_MAX);
|
||||
|
||||
RTCx->YEAR = TimeValue & RTC_YEAR_MASK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get current time value for each type time type
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] Timetype Time Type, should be:
|
||||
* - RTC_TIMETYPE_SECOND
|
||||
* - RTC_TIMETYPE_MINUTE
|
||||
* - RTC_TIMETYPE_HOUR
|
||||
* - RTC_TIMETYPE_DAYOFWEEK
|
||||
* - RTC_TIMETYPE_DAYOFMONTH
|
||||
* - RTC_TIMETYPE_DAYOFYEAR
|
||||
* - RTC_TIMETYPE_MONTH
|
||||
* - RTC_TIMETYPE_YEAR
|
||||
* @return Value of time according to specified time type
|
||||
**********************************************************************/
|
||||
uint32_t RTC_GetTime(LPC_RTC_Type *RTCx, uint32_t Timetype)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
CHECK_PARAM(PARAM_RTC_TIMETYPE(Timetype));
|
||||
|
||||
switch (Timetype)
|
||||
{
|
||||
case RTC_TIMETYPE_SECOND:
|
||||
return (RTCx->SEC & RTC_SEC_MASK);
|
||||
case RTC_TIMETYPE_MINUTE:
|
||||
return (RTCx->MIN & RTC_MIN_MASK);
|
||||
case RTC_TIMETYPE_HOUR:
|
||||
return (RTCx->HRS & RTC_HOUR_MASK);
|
||||
case RTC_TIMETYPE_DAYOFWEEK:
|
||||
return (RTCx->DOW & RTC_DOW_MASK);
|
||||
case RTC_TIMETYPE_DAYOFMONTH:
|
||||
return (RTCx->DOM & RTC_DOM_MASK);
|
||||
case RTC_TIMETYPE_DAYOFYEAR:
|
||||
return (RTCx->DOY & RTC_DOY_MASK);
|
||||
case RTC_TIMETYPE_MONTH:
|
||||
return (RTCx->MONTH & RTC_MONTH_MASK);
|
||||
case RTC_TIMETYPE_YEAR:
|
||||
return (RTCx->YEAR & RTC_YEAR_MASK);
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set full of time in RTC peripheral
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] pFullTime Pointer to a RTC_TIME_Type structure that
|
||||
* contains time value in full.
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RTC_SetFullTime (LPC_RTC_Type *RTCx, RTC_TIME_Type *pFullTime)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
|
||||
RTCx->DOM = pFullTime->DOM & RTC_DOM_MASK;
|
||||
RTCx->DOW = pFullTime->DOW & RTC_DOW_MASK;
|
||||
RTCx->DOY = pFullTime->DOY & RTC_DOY_MASK;
|
||||
RTCx->HRS = pFullTime->HOUR & RTC_HOUR_MASK;
|
||||
RTCx->MIN = pFullTime->MIN & RTC_MIN_MASK;
|
||||
RTCx->SEC = pFullTime->SEC & RTC_SEC_MASK;
|
||||
RTCx->MONTH = pFullTime->MONTH & RTC_MONTH_MASK;
|
||||
RTCx->YEAR = pFullTime->YEAR & RTC_YEAR_MASK;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get full of time in RTC peripheral
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] pFullTime Pointer to a RTC_TIME_Type structure that
|
||||
* will be stored time in full.
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RTC_GetFullTime (LPC_RTC_Type *RTCx, RTC_TIME_Type *pFullTime)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
|
||||
pFullTime->DOM = RTCx->DOM & RTC_DOM_MASK;
|
||||
pFullTime->DOW = RTCx->DOW & RTC_DOW_MASK;
|
||||
pFullTime->DOY = RTCx->DOY & RTC_DOY_MASK;
|
||||
pFullTime->HOUR = RTCx->HRS & RTC_HOUR_MASK;
|
||||
pFullTime->MIN = RTCx->MIN & RTC_MIN_MASK;
|
||||
pFullTime->SEC = RTCx->SEC & RTC_SEC_MASK;
|
||||
pFullTime->MONTH = RTCx->MONTH & RTC_MONTH_MASK;
|
||||
pFullTime->YEAR = RTCx->YEAR & RTC_YEAR_MASK;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set alarm time value for each time type
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] Timetype Time Type, should be:
|
||||
* - RTC_TIMETYPE_SECOND
|
||||
* - RTC_TIMETYPE_MINUTE
|
||||
* - RTC_TIMETYPE_HOUR
|
||||
* - RTC_TIMETYPE_DAYOFWEEK
|
||||
* - RTC_TIMETYPE_DAYOFMONTH
|
||||
* - RTC_TIMETYPE_DAYOFYEAR
|
||||
* - RTC_TIMETYPE_MONTH
|
||||
* - RTC_TIMETYPE_YEAR
|
||||
* @param[in] ALValue Alarm time value to set
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RTC_SetAlarmTime (LPC_RTC_Type *RTCx, uint32_t Timetype, uint32_t ALValue)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
|
||||
switch (Timetype)
|
||||
{
|
||||
case RTC_TIMETYPE_SECOND:
|
||||
CHECK_PARAM(ALValue <= RTC_SECOND_MAX);
|
||||
|
||||
RTCx->ASEC = ALValue & RTC_SEC_MASK;
|
||||
break;
|
||||
|
||||
case RTC_TIMETYPE_MINUTE:
|
||||
CHECK_PARAM(ALValue <= RTC_MINUTE_MAX);
|
||||
|
||||
RTCx->AMIN = ALValue & RTC_MIN_MASK;
|
||||
break;
|
||||
|
||||
case RTC_TIMETYPE_HOUR:
|
||||
CHECK_PARAM(ALValue <= RTC_HOUR_MAX);
|
||||
|
||||
RTCx->AHRS = ALValue & RTC_HOUR_MASK;
|
||||
break;
|
||||
|
||||
case RTC_TIMETYPE_DAYOFWEEK:
|
||||
CHECK_PARAM(ALValue <= RTC_DAYOFWEEK_MAX);
|
||||
|
||||
RTCx->ADOW = ALValue & RTC_DOW_MASK;
|
||||
break;
|
||||
|
||||
case RTC_TIMETYPE_DAYOFMONTH:
|
||||
CHECK_PARAM((ALValue <= RTC_DAYOFMONTH_MAX) \
|
||||
&& (ALValue >= RTC_DAYOFMONTH_MIN));
|
||||
|
||||
RTCx->ADOM = ALValue & RTC_DOM_MASK;
|
||||
break;
|
||||
|
||||
case RTC_TIMETYPE_DAYOFYEAR:
|
||||
CHECK_PARAM((ALValue >= RTC_DAYOFYEAR_MIN) \
|
||||
&& (ALValue <= RTC_DAYOFYEAR_MAX));
|
||||
|
||||
RTCx->ADOY = ALValue & RTC_DOY_MASK;
|
||||
break;
|
||||
|
||||
case RTC_TIMETYPE_MONTH:
|
||||
CHECK_PARAM((ALValue >= RTC_MONTH_MIN) \
|
||||
&& (ALValue <= RTC_MONTH_MAX));
|
||||
|
||||
RTCx->AMON = ALValue & RTC_MONTH_MASK;
|
||||
break;
|
||||
|
||||
case RTC_TIMETYPE_YEAR:
|
||||
CHECK_PARAM(ALValue <= RTC_YEAR_MAX);
|
||||
|
||||
RTCx->AYRS = ALValue & RTC_YEAR_MASK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get alarm time value for each time type
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] Timetype Time Type, should be:
|
||||
* - RTC_TIMETYPE_SECOND
|
||||
* - RTC_TIMETYPE_MINUTE
|
||||
* - RTC_TIMETYPE_HOUR
|
||||
* - RTC_TIMETYPE_DAYOFWEEK
|
||||
* - RTC_TIMETYPE_DAYOFMONTH
|
||||
* - RTC_TIMETYPE_DAYOFYEAR
|
||||
* - RTC_TIMETYPE_MONTH
|
||||
* - RTC_TIMETYPE_YEAR
|
||||
* @return Value of Alarm time according to specified time type
|
||||
**********************************************************************/
|
||||
uint32_t RTC_GetAlarmTime (LPC_RTC_Type *RTCx, uint32_t Timetype)
|
||||
{
|
||||
switch (Timetype)
|
||||
{
|
||||
case RTC_TIMETYPE_SECOND:
|
||||
return (RTCx->ASEC & RTC_SEC_MASK);
|
||||
case RTC_TIMETYPE_MINUTE:
|
||||
return (RTCx->AMIN & RTC_MIN_MASK);
|
||||
case RTC_TIMETYPE_HOUR:
|
||||
return (RTCx->AHRS & RTC_HOUR_MASK);
|
||||
case RTC_TIMETYPE_DAYOFWEEK:
|
||||
return (RTCx->ADOW & RTC_DOW_MASK);
|
||||
case RTC_TIMETYPE_DAYOFMONTH:
|
||||
return (RTCx->ADOM & RTC_DOM_MASK);
|
||||
case RTC_TIMETYPE_DAYOFYEAR:
|
||||
return (RTCx->ADOY & RTC_DOY_MASK);
|
||||
case RTC_TIMETYPE_MONTH:
|
||||
return (RTCx->AMON & RTC_MONTH_MASK);
|
||||
case RTC_TIMETYPE_YEAR:
|
||||
return (RTCx->AYRS & RTC_YEAR_MASK);
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set full of alarm time in RTC peripheral
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] pFullTime Pointer to a RTC_TIME_Type structure that
|
||||
* contains alarm time value in full.
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RTC_SetFullAlarmTime (LPC_RTC_Type *RTCx, RTC_TIME_Type *pFullTime)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
|
||||
RTCx->ADOM = pFullTime->DOM & RTC_DOM_MASK;
|
||||
RTCx->ADOW = pFullTime->DOW & RTC_DOW_MASK;
|
||||
RTCx->ADOY = pFullTime->DOY & RTC_DOY_MASK;
|
||||
RTCx->AHRS = pFullTime->HOUR & RTC_HOUR_MASK;
|
||||
RTCx->AMIN = pFullTime->MIN & RTC_MIN_MASK;
|
||||
RTCx->ASEC = pFullTime->SEC & RTC_SEC_MASK;
|
||||
RTCx->AMON = pFullTime->MONTH & RTC_MONTH_MASK;
|
||||
RTCx->AYRS = pFullTime->YEAR & RTC_YEAR_MASK;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get full of alarm time in RTC peripheral
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] pFullTime Pointer to a RTC_TIME_Type structure that
|
||||
* will be stored alarm time in full.
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RTC_GetFullAlarmTime (LPC_RTC_Type *RTCx, RTC_TIME_Type *pFullTime)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
|
||||
pFullTime->DOM = RTCx->ADOM & RTC_DOM_MASK;
|
||||
pFullTime->DOW = RTCx->ADOW & RTC_DOW_MASK;
|
||||
pFullTime->DOY = RTCx->ADOY & RTC_DOY_MASK;
|
||||
pFullTime->HOUR = RTCx->AHRS & RTC_HOUR_MASK;
|
||||
pFullTime->MIN = RTCx->AMIN & RTC_MIN_MASK;
|
||||
pFullTime->SEC = RTCx->ASEC & RTC_SEC_MASK;
|
||||
pFullTime->MONTH = RTCx->AMON & RTC_MONTH_MASK;
|
||||
pFullTime->YEAR = RTCx->AYRS & RTC_YEAR_MASK;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Check whether if specified Location interrupt in
|
||||
* RTC peripheral is set or not
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] IntType Interrupt location type, should be:
|
||||
* - RTC_INT_COUNTER_INCREASE: Counter Increment Interrupt block generated an interrupt.
|
||||
* - RTC_INT_ALARM: Alarm generated an interrupt.
|
||||
* @return New state of specified Location interrupt in RTC peripheral
|
||||
* - SET
|
||||
* - RESET
|
||||
**********************************************************************/
|
||||
IntStatus RTC_GetIntPending (LPC_RTC_Type *RTCx, uint32_t IntType)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
CHECK_PARAM(PARAM_RTC_INT(IntType));
|
||||
|
||||
return ((RTCx->ILR & IntType) ? SET : RESET);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Clear specified Location interrupt pending in
|
||||
* RTC peripheral
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] IntType Interrupt location type, should be:
|
||||
* - RTC_INT_COUNTER_INCREASE :Clear Counter Increment Interrupt pending.
|
||||
* - RTC_INT_ALARM :Clear alarm interrupt pending
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RTC_ClearIntPending (LPC_RTC_Type *RTCx, uint32_t IntType)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
CHECK_PARAM(PARAM_RTC_INT(IntType));
|
||||
|
||||
RTCx->ILR = IntType;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable/Disable calibration counter in RTC peripheral
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] NewState New State of this function, should be:
|
||||
* - ENABLE :The calibration counter is enabled and counting
|
||||
* - DISABLE :The calibration counter is disabled and reset to zero
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RTC_CalibCounterCmd(LPC_RTC_Type *RTCx, FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
|
||||
|
||||
if (NewState == ENABLE)
|
||||
{
|
||||
do
|
||||
{
|
||||
RTCx->CCR &= (~RTC_CCR_CCALEN) & RTC_CCR_BITMASK;
|
||||
}while(RTCx->CCR&RTC_CCR_CCALEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
RTCx->CCR |= RTC_CCR_CCALEN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Configures Calibration in RTC peripheral
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] CalibValue Calibration value, should be in range from
|
||||
* 0 to 131,072
|
||||
* @param[in] CalibDir Calibration Direction, should be:
|
||||
* - RTC_CALIB_DIR_FORWARD :Forward calibration
|
||||
* - RTC_CALIB_DIR_BACKWARD :Backward calibration
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void RTC_CalibConfig(LPC_RTC_Type *RTCx, uint32_t CalibValue, uint8_t CalibDir)
|
||||
{
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
CHECK_PARAM(PARAM_RTC_CALIB_DIR(CalibDir));
|
||||
CHECK_PARAM(CalibValue < RTC_CALIBRATION_MAX);
|
||||
|
||||
RTCx->CALIBRATION = (CalibValue & RTC_CALIBRATION_CALVAL_MASK) \
|
||||
| ((CalibDir == RTC_CALIB_DIR_BACKWARD) ? RTC_CALIBRATION_LIBDIR : 0);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Write value to General purpose registers
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] Channel General purpose registers Channel number,
|
||||
* should be in range from 0 to 63.
|
||||
* @param[in] Value Value to write
|
||||
* @return None
|
||||
* Note: These General purpose registers can be used to store important
|
||||
* information when the main power supply is off. The value in these
|
||||
* registers is not affected by chip reset.
|
||||
**********************************************************************/
|
||||
void RTC_WriteGPREG (LPC_RTC_Type *RTCx, uint8_t Channel, uint32_t Value)
|
||||
{
|
||||
uint32_t *preg;
|
||||
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
CHECK_PARAM(PARAM_RTC_GPREG_CH(Channel));
|
||||
|
||||
preg = (uint32_t *)RTC_GPREG_BASE;
|
||||
preg += Channel;
|
||||
*preg = Value;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Read value from General purpose registers
|
||||
* @param[in] RTCx RTC peripheral selected, should be LPC_RTC
|
||||
* @param[in] Channel General purpose registers Channel number,
|
||||
* should be in range from 0 to 4.
|
||||
* @return Read Value
|
||||
* Note: These General purpose registers can be used to store important
|
||||
* information when the main power supply is off. The value in these
|
||||
* registers is not affected by chip reset.
|
||||
**********************************************************************/
|
||||
uint32_t RTC_ReadGPREG (LPC_RTC_Type *RTCx, uint8_t Channel)
|
||||
{
|
||||
uint32_t *preg;
|
||||
uint32_t value;
|
||||
|
||||
CHECK_PARAM(PARAM_RTCx(RTCx));
|
||||
CHECK_PARAM(PARAM_RTC_GPREG_CH(Channel));
|
||||
|
||||
preg = (uint32_t *)RTC_GPREG_BASE;
|
||||
preg += Channel;
|
||||
value = *preg;
|
||||
return (value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _RTC */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* --------------------------------- End Of File ------------------------------ */
|
||||
@@ -0,0 +1,145 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_sct.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_sct.c
|
||||
* @brief Contains all functions support for SCT firmware library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup SCT
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_sct.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
|
||||
#ifdef _SCT
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup SCT_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Select 16/32 bit SCT counter
|
||||
* @param[in] value configuration value for SCT
|
||||
* - SCT_CONFIG_16BIT_COUNTER :16-bit counter
|
||||
* - SCT_CONFIG_32BIT_COUNTER :32-bit counter
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void SCT_Config(uint32_t value)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SCT_CONFIG_COUNTER_TYPE(value));
|
||||
|
||||
LPC_SCT->CONFIG = value;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Setting SCT control
|
||||
* @param[in] value setting value
|
||||
* @param[in] ena Enable/disable status
|
||||
* - ENABLE
|
||||
* - DISABLE
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void SCT_ControlSet(uint32_t value, FunctionalState ena)
|
||||
{
|
||||
uint32_t tem;
|
||||
|
||||
CHECK_PARAM(PARAM_FUNCTIONALSTATE(ena));
|
||||
|
||||
tem = LPC_SCT->CTRL_U;
|
||||
|
||||
if(ena == ENABLE)
|
||||
{
|
||||
tem |= value;
|
||||
}
|
||||
else
|
||||
{
|
||||
tem &= (~value);
|
||||
}
|
||||
|
||||
LPC_SCT->CTRL_U = tem;
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set start mode for ADC
|
||||
* @param[in] outnum number of SCT output, should be: 0..15
|
||||
* @param[in] value solution value, should be
|
||||
* - SCT_RES_NOCHANGE :No change
|
||||
* - SCT_RES_SET_OUTPUT :Set output
|
||||
* - SCT_RES_CLEAR_OUTPUT :Clear output
|
||||
* - SCT_RES_TOGGLE_OUTPUT :Toggle output
|
||||
* @return None
|
||||
*********************************************************************/
|
||||
void SCT_ConflictResolutionSet(uint8_t outnum, uint8_t value)
|
||||
{
|
||||
uint32_t tem;
|
||||
|
||||
CHECK_PARAM(PARAM_SCT_OUTPUT_NUM(outnum));
|
||||
CHECK_PARAM(PARAM_SCT_RES(value));
|
||||
|
||||
tem = LPC_SCT->RES;
|
||||
tem &= ~(0x03 << (2*outnum));
|
||||
tem |= (value << (2*outnum));
|
||||
LPC_SCT->RES = tem;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Clear SCT event generating interrupt request
|
||||
* @param[in] even_num SCT event number, should be: 0..15
|
||||
* @return None
|
||||
*********************************************************************/
|
||||
void SCT_EventFlagClear(uint8_t even_num)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SCT_EVENT(even_num));
|
||||
|
||||
LPC_SCT->EVFLAG = (1 << (even_num));
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _SCT */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* --------------------------------- End Of File ------------------------------ */
|
||||
@@ -0,0 +1,106 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_scu.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_scu.c
|
||||
* @brief Contains all functions support for SCU firmware library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors�
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup SCU
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "LPC43xx.h" /* lpc43xx definitions */
|
||||
#include "lpc_types.h"
|
||||
#include "lpc43xx_scu.h"
|
||||
|
||||
/* Pin modes
|
||||
* =========
|
||||
* The EPUN and EPD bits in the SFS registers allow the selection of weak on-chip
|
||||
* pull-up or pull-down resistors with a typical value of 50 kOhm for each pin or the
|
||||
* selection of the repeater mode.
|
||||
* The possible on-chip resistor configurations are pull-up enabled, pull-down enabled, or no
|
||||
* pull-up/pull-down. The default value is pull-up enabled.
|
||||
*
|
||||
* The repeater mode enables the pull-up resistor if the pin is at a logic HIGH and enables
|
||||
* the pull-down resistor if the pin is at a logic LOW. This causes the pin to retain its last
|
||||
* known state if it is configured as an input and is not driven externally. Repeater mode may
|
||||
* typically be used to prevent a pin from floating (and potentially using significant power if it
|
||||
* floats to an indeterminate state) if it is temporarily not driven.
|
||||
* Repeater mode is enabled when both pull-up and pull-down are enabled.
|
||||
*
|
||||
* To be able to receive a digital signal, the input buffer must be enabled through bit EZI in
|
||||
* the pin configuration registers. By default, the input buffer is disabled.
|
||||
* For pads that support both a digital and an analog function, the input buffer must be
|
||||
* disabled before enabling the analog function.
|
||||
*
|
||||
* All digital pins support a programmable glitch filter (bit ZIF), which can be switched on or
|
||||
* off. By default, the glitch filter is on. The glitch filter should be disabled for
|
||||
* clocking signals with frequencies higher than 30 MHz.
|
||||
*
|
||||
* Normal-drive and high-speed pins support a programmable slew rate (bit EHS) to select
|
||||
* between lower noise and low speed or higher noise and high speed . The typical
|
||||
* frequencies supported are 50 MHz/80 MHz for normal-drive pins and 75 MHz/180 MHz for
|
||||
* high-speed pins.
|
||||
*/
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Configure pin function
|
||||
* @param[in] port Port number, should be: 0..15
|
||||
* @param[in] pin Pin number, should be: 0..31
|
||||
* @param[in] mode Pin mode, should be:
|
||||
* - MD_PUP :Pull-up enabled
|
||||
* - MD_BUK :Plain input
|
||||
* - MD_PLN :Repeater mode
|
||||
* - MD_PDN :Pull-down enabled
|
||||
* - MD_EHS :Slew rate
|
||||
* - MD_EZI :Input buffer enable
|
||||
* - MD_ZI :Glitch filter enabled
|
||||
* - MD_EHD0 :High drive 8 mA
|
||||
* - MD_EHD1 :High drive 14 mA
|
||||
* - MD_EHD2 :High drive 20 mA
|
||||
* @param[in] func Function mode, should be:
|
||||
* - FUNC0 :Function 0
|
||||
* - FUNC1 :Function 1
|
||||
* - FUNC2 :Function 2
|
||||
* - FUNC3 :Function 3
|
||||
* - FUNC4 :Function 4
|
||||
* - FUNC5 :Function 5
|
||||
* - FUNC6 :Function 6
|
||||
* - FUNC7 :Function 7
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void scu_pinmux(uint8_t port, uint8_t pin, uint8_t mode, uint8_t func)
|
||||
{
|
||||
uint32_t * scu_base=(uint32_t*)(LPC_SCU_BASE);
|
||||
scu_base[(PORT_OFFSET*port+PIN_OFFSET*pin)/4]=mode+func;
|
||||
} /* scu_pinmux */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,401 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_sdif.c 2012-Aug-15
|
||||
*//**
|
||||
* @file lpc43xx_sdif.c
|
||||
* @brief LPC43xx SD interface driver
|
||||
* @version 1.0
|
||||
* @date 15. Aug. 2012
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors'
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup SDIF
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "LPC43xx.h" /* LPC43xx definitions */
|
||||
#include "system_LPC43xx.h"
|
||||
#include "lpc_sdmmc.h"
|
||||
#include "lpc43xx_sdif.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
#ifdef _SDIF
|
||||
|
||||
/* Local data structure for the SDIF driver */
|
||||
struct _sdif_device {
|
||||
MCI_IRQ_CB_FUNC_T irq_cb;
|
||||
LPC_SDMMC_DMA_Type mci_dma_dd[1 + (0x10000 / MCI_DMADES1_MAXTR)];
|
||||
uint32_t sdio_clk_rate;
|
||||
uint32_t sdif_slot_clk_rate;
|
||||
int32_t clock_enabled;
|
||||
};
|
||||
static struct _sdif_device sdif_dev;
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enables the SDIO controller clock
|
||||
* @param[in] None
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
static void sdif_enable_clock(void)
|
||||
{
|
||||
if (!sdif_dev.clock_enabled)
|
||||
{
|
||||
/* Enable SD MMC clock */
|
||||
CGU_ConfigPWR(CGU_PERIPHERAL_SDIO, ENABLE);
|
||||
sdif_dev.clock_enabled = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Disables the SDIO controller clock
|
||||
* @param[in] None
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
static void sdif_disable_clock(void)
|
||||
{
|
||||
if (!sdif_dev.clock_enabled)
|
||||
{
|
||||
/* Disable SD MMC clock */
|
||||
CGU_ConfigPWR(CGU_PERIPHERAL_SDIO, (FunctionalState)FALSE);
|
||||
sdif_dev.clock_enabled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @defgroup SDIF_Public_Functions
|
||||
* @ingroup SDIF
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Setup DMA descriptors
|
||||
* @param[in] addr Address of buffer (source or destination)
|
||||
* @param[in] size size of buffer in bytes (64K max)
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void sdif_dma_setup(uint32_t addr, uint32_t size)
|
||||
{
|
||||
int i = 0;
|
||||
uint32_t ctrl, maxs;
|
||||
|
||||
/* Reset DMA */
|
||||
LPC_SDMMC->CTRL |= MCI_CTRL_DMA_RESET | MCI_CTRL_FIFO_RESET;
|
||||
while (LPC_SDMMC->CTRL & MCI_CTRL_DMA_RESET);
|
||||
|
||||
/* Build a descriptor list using the chained DMA method */
|
||||
while (size > 0)
|
||||
{
|
||||
/* Limit size of the transfer to maximum buffer size */
|
||||
maxs = size;
|
||||
if (maxs > MCI_DMADES1_MAXTR)
|
||||
maxs = MCI_DMADES1_MAXTR;
|
||||
size -= maxs;
|
||||
|
||||
/* Set buffer size */
|
||||
sdif_dev.mci_dma_dd[i].des1 = MCI_DMADES1_BS1(maxs);
|
||||
|
||||
/* Setup buffer address (chained) */
|
||||
sdif_dev.mci_dma_dd[i].des2 = addr + (i * MCI_DMADES1_MAXTR);
|
||||
|
||||
/* Setup basic control */
|
||||
ctrl = MCI_DMADES0_OWN | MCI_DMADES0_CH;
|
||||
if (i == 0)
|
||||
ctrl |= MCI_DMADES0_FS; /* First DMA buffer */
|
||||
|
||||
/* No more data? Then this is the last descriptor */
|
||||
if (!size)
|
||||
ctrl |= MCI_DMADES0_LD;
|
||||
else
|
||||
ctrl |= MCI_DMADES0_DIC;
|
||||
|
||||
/* Another descriptor is needed */
|
||||
sdif_dev.mci_dma_dd[i].des3 = (uint32_t) &sdif_dev.mci_dma_dd[i + 1];
|
||||
sdif_dev.mci_dma_dd[i].des0 = ctrl;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Set DMA derscriptor base address */
|
||||
LPC_SDMMC->DBADDR = (uint32_t) &sdif_dev.mci_dma_dd[0];
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Function to send command to Card interface unit (CIU)
|
||||
* @param[in] cmd Command with all flags set
|
||||
* @param[in] arg Argument for the command
|
||||
* @return TRUE on times-out, otherwise FALSE
|
||||
**********************************************************************/
|
||||
int32_t sdif_send_cmd(uint32_t cmd, uint32_t arg)
|
||||
{
|
||||
volatile int32_t tmo = 50;
|
||||
volatile int delay;
|
||||
|
||||
/* set command arg reg*/
|
||||
LPC_SDMMC->CMDARG = arg;
|
||||
LPC_SDMMC->CMD = MCI_CMD_START | cmd;
|
||||
|
||||
/* poll untill command is accepted by the CIU */
|
||||
while (--tmo && (LPC_SDMMC->CMD & MCI_CMD_START))
|
||||
{
|
||||
if (tmo & 1)
|
||||
delay = 50;
|
||||
else
|
||||
delay = 18000;
|
||||
|
||||
while (--delay > 1);
|
||||
}
|
||||
|
||||
return (tmo < 1) ? 1 : 0;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Function to retrieve command response
|
||||
* @param[in] pdev Pointer to card info structure
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void sdif_get_response(uint32_t *resp)
|
||||
{
|
||||
/* on this chip response is not a fifo so read all 4 regs */
|
||||
resp[0] = LPC_SDMMC->RESP0;
|
||||
resp[1] = LPC_SDMMC->RESP1;
|
||||
resp[2] = LPC_SDMMC->RESP2;
|
||||
resp[3] = LPC_SDMMC->RESP3;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Function to set speed of the clock going to card
|
||||
* @param[in] speed Desired clock speed to the card
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void sdif_set_clock(uint32_t speed)
|
||||
{
|
||||
/* compute SD/MMC clock dividers */
|
||||
uint32_t div;
|
||||
|
||||
/* Exit if the clock is already set at the passed speed */
|
||||
if (sdif_dev.sdif_slot_clk_rate == speed)
|
||||
return;
|
||||
|
||||
div = ((sdif_dev.sdio_clk_rate / speed) + 2) >> 1;
|
||||
sdif_dev.sdif_slot_clk_rate = speed;
|
||||
|
||||
if ((div == LPC_SDMMC->CLKDIV) && LPC_SDMMC->CLKENA)
|
||||
return; /* Closest speed is already set */
|
||||
|
||||
/* disable clock */
|
||||
LPC_SDMMC->CLKENA = 0;
|
||||
|
||||
/* User divider 0 */
|
||||
LPC_SDMMC->CLKSRC = MCI_CLKSRC_CLKDIV0;
|
||||
|
||||
/* inform CIU */
|
||||
sdif_send_cmd(MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0);
|
||||
|
||||
/* set divider 0 to desired value */
|
||||
LPC_SDMMC->CLKDIV = MCI_CLOCK_DIVIDER(0, div);
|
||||
|
||||
/* inform CIU */
|
||||
sdif_send_cmd(MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0);
|
||||
|
||||
/* enable clock */
|
||||
LPC_SDMMC->CLKENA = MCI_CLKEN_ENABLE;
|
||||
|
||||
/* inform CIU */
|
||||
sdif_send_cmd(MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Detect if an SD card is inserted
|
||||
* @param[in] None
|
||||
* @return Returns 0 if a card is detected, otherwise 1
|
||||
**********************************************************************/
|
||||
int32_t sdif_card_ndetect(void)
|
||||
{
|
||||
/* No card = high state in regsiter */
|
||||
if (LPC_SDMMC->CDETECT & 1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Detect if write protect is enabled
|
||||
* @param[in] None
|
||||
* @return Returns 1 if card is write protected, otherwise 0
|
||||
**********************************************************************/
|
||||
int32_t sdif_card_wp_on(void)
|
||||
{
|
||||
if (LPC_SDMMC->WRTPRT & 1)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable or disable slot power
|
||||
* @param[in] enable !0 to enable, or 0 to disable
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void sdif_power_onoff(int32_t enable)
|
||||
{
|
||||
if (enable)
|
||||
LPC_SDMMC->PWREN = 1;
|
||||
else
|
||||
LPC_SDMMC->PWREN = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Reset card in slot
|
||||
* @param[in] reset Sets SD_RST to passed state
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void sdif_reset(int32_t reset)
|
||||
{
|
||||
if (reset)
|
||||
LPC_SDMMC->RST_N = 1;
|
||||
else
|
||||
LPC_SDMMC->RST_N = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Set block size for transfer
|
||||
* @param[in] bytes Lock size in bytes
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void sdif_set_blksize(uint32_t bytes)
|
||||
{
|
||||
LPC_SDMMC->BLKSIZ = bytes;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enter or exit low power mode (disables clocking)
|
||||
* @param[in] lpmode !0 to enable low power mode, 0 = exit
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void sdif_set_lowpower_mode(int32_t lpmode)
|
||||
{
|
||||
/* Once in low power mode, no SDIF functions should ever be
|
||||
called, as it can hang the chip. Always exit low power mode
|
||||
prior to resuming SDIF functions */
|
||||
if (lpmode)
|
||||
sdif_disable_clock();
|
||||
else
|
||||
sdif_enable_clock();
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Initializes the MCI card controller
|
||||
* @param[in] waitfunc Pointer to wait function to be used during for poll command status
|
||||
* @param[in] irq_callback Pointer to IRQ callback function
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void sdif_init(uint32_t sdio_clock, MCI_IRQ_CB_FUNC_T irq_callback)
|
||||
{
|
||||
volatile uint32_t i;
|
||||
|
||||
sdif_dev.sdio_clk_rate = sdio_clock;
|
||||
sdif_dev.irq_cb = irq_callback;
|
||||
|
||||
/* enable SD/MMC clock */
|
||||
sdif_enable_clock();
|
||||
|
||||
/* Software reset */
|
||||
LPC_SDMMC->BMOD = MCI_BMOD_SWR;
|
||||
|
||||
/* reset all blocks */
|
||||
LPC_SDMMC->CTRL = MCI_CTRL_RESET | MCI_CTRL_FIFO_RESET |
|
||||
MCI_CTRL_DMA_RESET;
|
||||
while (LPC_SDMMC->CTRL &
|
||||
(MCI_CTRL_RESET | MCI_CTRL_FIFO_RESET | MCI_CTRL_DMA_RESET));
|
||||
|
||||
/* Internal DMA setup for control register */
|
||||
LPC_SDMMC->CTRL = MCI_CTRL_USE_INT_DMAC | MCI_CTRL_INT_ENABLE;
|
||||
LPC_SDMMC->INTMASK = 0;
|
||||
|
||||
/* Clear the interrupts for the host controller */
|
||||
LPC_SDMMC->RINTSTS = 0xFFFFFFFF;
|
||||
|
||||
/* Put in max timeout */
|
||||
LPC_SDMMC->TMOUT = 0xFFFFFFFF;
|
||||
|
||||
/* FIFO threshold settings for DMA, DMA burst of 4,
|
||||
FIFO watermark at 16 */
|
||||
LPC_SDMMC->FIFOTH = MCI_FIFOTH_DMA_MTS_4 |
|
||||
MCI_FIFOTH_RX_WM((SD_FIFO_SZ / 2) - 1) |
|
||||
MCI_FIFOTH_TX_WM(SD_FIFO_SZ / 2);
|
||||
|
||||
/* Enable internal DMA, burst size of 4, fixed burst */
|
||||
LPC_SDMMC->BMOD = MCI_BMOD_DE | MCI_BMOD_PBL4 | MCI_BMOD_DSL(4);
|
||||
|
||||
/* disable clock to CIU (needs latch) */
|
||||
LPC_SDMMC->CLKENA = 0;
|
||||
LPC_SDMMC->CLKSRC = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Close the MCI
|
||||
* @param[in] None
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void sdif_deinit(void)
|
||||
{
|
||||
/* clear mmc structure*/
|
||||
sdif_disable_clock();
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief SDIO controller interrupt handler
|
||||
* @param[in] None
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void SDIO_IRQHandler(void)
|
||||
{
|
||||
/* All SD based register handling is done in the callback
|
||||
function. The SDIO interrupt is not enabled as part of this
|
||||
driver and needs to be enabled/disabled in the callbacks or
|
||||
application as needed. This is to allow flexibility with IRQ
|
||||
handling for applicaitons and RTOSes. */
|
||||
sdif_dev.irq_cb(LPC_SDMMC->RINTSTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _SDIF */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,694 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_sdmmc.c 2012-Aug-15
|
||||
*//**
|
||||
* @file lpc43xx_sdmmc.c
|
||||
* @brief SD/MMC card access and data driver
|
||||
* @version 1.0
|
||||
* @date 15. Aug. 2012
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors'
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Example group ----------------------------------------------------------- */
|
||||
/** @addtogroup SDMMC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "string.h"
|
||||
#include "lpc_sdmmc.h"
|
||||
#include "lpc43xx_sdif.h"
|
||||
#include "lpc43xx_sdmmc.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
#ifdef _SDMMC
|
||||
|
||||
/* Global instance of the current card */
|
||||
static struct _mci_card_struct *g_card_info;
|
||||
|
||||
/* Pointer to event setup functions */
|
||||
static MCI_EVSETUP_FUNC_T sdmmc_evsetup_cb;
|
||||
|
||||
/* Pointer to wait functions */
|
||||
static MCI_WAIT_CB_FUNC_T sdmmc_wait_cb;
|
||||
|
||||
/* Pointer to mS delay functin */
|
||||
static MCI_MSDELAY_FUNC_T sdmmc_msdelay_cb;
|
||||
|
||||
/* Helper definition: all SD error conditions in the status word */
|
||||
#define SD_INT_ERROR (MCI_INT_RESP_ERR | MCI_INT_RCRC | MCI_INT_DCRC | \
|
||||
MCI_INT_RTO | MCI_INT_DTO | MCI_INT_HTO | MCI_INT_FRUN | MCI_INT_HLE | \
|
||||
MCI_INT_SBE | MCI_INT_EBE)
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Helper function to get a bit field withing multi-word
|
||||
* buffer. Used to get fields with-in CSD & EXT-CSD
|
||||
* structures.
|
||||
* @param[in] start Starting bit
|
||||
* @param[in] end Ending bit
|
||||
* @param[in] data Pointer to data patternf or bit extraction
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
static uint32_t prv_get_bits(int32_t start, int32_t end, uint32_t* data)
|
||||
{
|
||||
uint32_t v;
|
||||
uint32_t i = end >> 5;
|
||||
uint32_t j = start & 0x1f;
|
||||
|
||||
if (i == (start >> 5))
|
||||
v = (data[i] >> j);
|
||||
else
|
||||
v = ((data[i] << (32 - j)) | (data[start >> 5] >> j));
|
||||
|
||||
return (v & ((1 << (end - start + 1)) - 1));
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Function to execute a command
|
||||
* @param[in] cmd Command with all flags set
|
||||
* @param[in] arg Argument for the command
|
||||
* @param[in] wait_status Status bits to poll for command completion
|
||||
* @return 0 on success, or error code (-1)
|
||||
**********************************************************************/
|
||||
static int32_t sdmmc_execute_command(uint32_t cmd, uint32_t arg,
|
||||
uint32_t wait_status)
|
||||
{
|
||||
int32_t step = (cmd & CMD_BIT_APP) ? 2 : 1;
|
||||
int32_t status = 0;
|
||||
uint32_t cmd_reg = 0;
|
||||
|
||||
if (!wait_status)
|
||||
wait_status = (cmd & CMD_MASK_RESP) ? MCI_INT_CMD_DONE : MCI_INT_DATA_OVER;
|
||||
|
||||
/* Clear the interrupts & FIFOs*/
|
||||
if (cmd & CMD_BIT_DATA)
|
||||
{
|
||||
/* reset all blocks */
|
||||
LPC_SDMMC->CTRL |= MCI_CTRL_FIFO_RESET;
|
||||
|
||||
/* wait till resets clear */
|
||||
while (LPC_SDMMC->CTRL & MCI_CTRL_FIFO_RESET);
|
||||
|
||||
/* Clear interrupt status */
|
||||
LPC_SDMMC->RINTSTS = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/* also check error conditions */
|
||||
wait_status |= MCI_INT_EBE | MCI_INT_SBE | MCI_INT_HLE |
|
||||
MCI_INT_RTO | MCI_INT_RCRC | MCI_INT_RESP_ERR;
|
||||
if (wait_status & MCI_INT_DATA_OVER)
|
||||
wait_status |= MCI_INT_FRUN | MCI_INT_HTO | MCI_INT_DTO | MCI_INT_DCRC;
|
||||
|
||||
while (step)
|
||||
{
|
||||
sdif_set_clock((cmd & CMD_BIT_LS) ? SD_MMC_ENUM_CLOCK : g_card_info->speed);
|
||||
|
||||
/* Clear the interrupts */
|
||||
LPC_SDMMC->RINTSTS = 0xFFFFFFFF;
|
||||
sdmmc_evsetup_cb(wait_status);
|
||||
|
||||
switch (step)
|
||||
{
|
||||
case 1: /* Execute command */
|
||||
cmd_reg = ((cmd & CMD_MASK_CMD) >> CMD_SHIFT_CMD) |
|
||||
((cmd & CMD_BIT_INIT) ? MCI_CMD_INIT : 0) |
|
||||
((cmd & CMD_BIT_DATA) ? (MCI_CMD_DAT_EXP | MCI_CMD_PRV_DAT_WAIT) : 0) |
|
||||
(((cmd & CMD_MASK_RESP) == CMD_RESP_R2) ? MCI_CMD_RESP_LONG : 0) |
|
||||
((cmd & CMD_MASK_RESP) ? MCI_CMD_RESP_EXP : 0) |
|
||||
((cmd & CMD_BIT_WRITE) ? MCI_CMD_DAT_WR : 0) |
|
||||
((cmd & CMD_BIT_STREAM) ? MCI_CMD_STRM_MODE : 0) |
|
||||
((cmd & CMD_BIT_BUSY) ? MCI_CMD_STOP : 0) |
|
||||
((cmd & CMD_BIT_AUTO_STOP) ? MCI_CMD_SEND_STOP : 0) |
|
||||
MCI_CMD_START;
|
||||
|
||||
/* wait for previos data finsh for select/deselect commands */
|
||||
if (((cmd & CMD_MASK_CMD) >> CMD_SHIFT_CMD) == MMC_SELECT_CARD)
|
||||
{
|
||||
cmd_reg |= MCI_CMD_PRV_DAT_WAIT;
|
||||
}
|
||||
|
||||
/* wait for command to be accepted by CIU */
|
||||
if (sdif_send_cmd(cmd_reg, arg) == 0)
|
||||
--step;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
return 0;
|
||||
|
||||
case 2: /* APP prefix */
|
||||
cmd_reg = MMC_APP_CMD | MCI_CMD_RESP_EXP |
|
||||
((cmd & CMD_BIT_INIT) ? MCI_CMD_INIT : 0) |
|
||||
MCI_CMD_START;
|
||||
|
||||
if (sdif_send_cmd(cmd_reg, g_card_info->rca << 16) == 0)
|
||||
--step;
|
||||
break;
|
||||
}
|
||||
|
||||
/* wait for command response */
|
||||
status = sdmmc_wait_cb(wait_status);
|
||||
|
||||
/* We return an error if there is a timeout, even if we've fetched
|
||||
a response */
|
||||
if (status & SD_INT_ERROR)
|
||||
return status;
|
||||
|
||||
if (status & MCI_INT_CMD_DONE)
|
||||
{
|
||||
switch (cmd & CMD_MASK_RESP)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case CMD_RESP_R1:
|
||||
case CMD_RESP_R3:
|
||||
sdif_get_response(&g_card_info->response[0]);
|
||||
break;
|
||||
|
||||
case CMD_RESP_R2:
|
||||
sdif_get_response(&g_card_info->response[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Checks whether card is acquired properly or not
|
||||
* @return !0 if card has been acquired, otherwise 0
|
||||
**********************************************************************/
|
||||
static int32_t prv_card_acquired(void)
|
||||
{
|
||||
return (g_card_info->cid[0] != 0);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Function to process the CSD & EXT-CSD of the card
|
||||
* @param[in] None
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
static void prv_process_csd(void)
|
||||
{
|
||||
int32_t status = 0;
|
||||
int32_t c_size = 0;
|
||||
int32_t c_size_mult = 0;
|
||||
int32_t mult = 0;
|
||||
|
||||
/* compute block length based on CSD response */
|
||||
g_card_info->block_len = 1 << prv_get_bits(80, 83, g_card_info->csd);
|
||||
|
||||
if ((g_card_info->card_type & CARD_TYPE_HC) &&
|
||||
(g_card_info->card_type & CARD_TYPE_SD))
|
||||
{
|
||||
/* See section 5.3.3 CSD Register (CSD Version 2.0) of SD2.0 spec
|
||||
an explanation for the calculation of these values */
|
||||
c_size = prv_get_bits(48, 63, (uint32_t*)g_card_info->csd) + 1;
|
||||
g_card_info->blocknr = c_size << 10; /* 512 byte blocks */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* See section 5.3 of the 4.1 revision of the MMC specs for
|
||||
an explanation for the calculation of these values */
|
||||
c_size = prv_get_bits(62, 73, (uint32_t*)g_card_info->csd);
|
||||
c_size_mult = prv_get_bits(47, 49, (uint32_t*)g_card_info->csd);
|
||||
mult = 1 << (c_size_mult + 2);
|
||||
g_card_info->blocknr = (c_size + 1) * mult;
|
||||
|
||||
/* adjust blocknr to 512/block */
|
||||
if (g_card_info->block_len > MMC_SECTOR_SIZE)
|
||||
g_card_info->blocknr = g_card_info->blocknr *
|
||||
(g_card_info->block_len >> 9);
|
||||
|
||||
/* get extended CSD for newer MMC cards CSD spec >= 4.0*/
|
||||
if (((g_card_info->card_type & CARD_TYPE_SD) == 0) &&
|
||||
(prv_get_bits(122, 125, (uint32_t*)g_card_info->csd) >= 4))
|
||||
{
|
||||
/* put card in trans state */
|
||||
status = sdmmc_execute_command(CMD_SELECT_CARD,
|
||||
g_card_info->rca << 16, 0);
|
||||
|
||||
/* set block size and byte count */
|
||||
LPC_SDMMC->BLKSIZ = MMC_SECTOR_SIZE;
|
||||
LPC_SDMMC->BYTCNT = MMC_SECTOR_SIZE;
|
||||
|
||||
/* send EXT_CSD command */
|
||||
sdif_dma_setup((uint32_t) g_card_info->ext_csd, MMC_SECTOR_SIZE);
|
||||
status = sdmmc_execute_command(CMD_SEND_EXT_CSD, 0, 0 |
|
||||
MCI_INT_DATA_OVER);
|
||||
if ((status & SD_INT_ERROR) == 0)
|
||||
{
|
||||
/* check EXT_CSD_VER is greater than 1.1 */
|
||||
if ((g_card_info->ext_csd[48] & 0xFF) > 1)
|
||||
g_card_info->blocknr = g_card_info->ext_csd[53]; /* bytes 212:215 represent sec count */
|
||||
|
||||
/* switch to 52MHz clock if card type is set to 1 or else set to 26MHz */
|
||||
if ((g_card_info->ext_csd[49] & 0xFF) == 1)
|
||||
{
|
||||
/* for type 1 MMC cards high speed is 52MHz */
|
||||
g_card_info->speed = MMC_HIGH_BUS_MAX_CLOCK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* for type 0 MMC cards high speed is 26MHz */
|
||||
g_card_info->speed = MMC_LOW_BUS_MAX_CLOCK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_card_info->device_size = g_card_info->blocknr << 9; /* blocknr * 512 */
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Puts current selected card in trans state
|
||||
* @param[in] None
|
||||
* @return 0 on success, or error code (-1)
|
||||
**********************************************************************/
|
||||
static int32_t prv_set_trans_state(void)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
/* get current state of the card */
|
||||
status = sdmmc_execute_command(CMD_SEND_STATUS, g_card_info->rca << 16, 0);
|
||||
if (status & MCI_INT_RTO)
|
||||
{
|
||||
/* unable to get the card state. So return immediatly. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check card state in response */
|
||||
status = R1_CURRENT_STATE(g_card_info->response[0]);
|
||||
switch (status)
|
||||
{
|
||||
case SDMMC_STBY_ST:
|
||||
/* put card in 'Trans' state */
|
||||
status = sdmmc_execute_command(CMD_SELECT_CARD, g_card_info->rca << 16, 0);
|
||||
if (status != 0)
|
||||
{
|
||||
/* unable to put the card in Trans state. So return immediatly. */
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDMMC_TRAN_ST:
|
||||
/*do nothing */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* card shouldn't be in other states so return */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Sets card data width and block size
|
||||
* @param[in] None
|
||||
* @return 0 on success, or error code (-1)
|
||||
**********************************************************************/
|
||||
static int32_t prv_set_card_params(void)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
#if SDIO_BUS_WIDTH > 1
|
||||
if (g_card_info->card_type & CARD_TYPE_SD)
|
||||
{
|
||||
status = sdmmc_execute_command(CMD_SD_SET_WIDTH, 2, 0);
|
||||
if (status != 0)
|
||||
return -1;
|
||||
|
||||
/* if positive response */
|
||||
LPC_SDMMC->CTYPE = MCI_CTYPE_4BIT;
|
||||
}
|
||||
#elif SDIO_BUS_WIDTH > 4
|
||||
#error 8-bit mode not supported yet!
|
||||
#endif
|
||||
|
||||
/* set block length */
|
||||
LPC_SDMMC->BLKSIZ = MMC_SECTOR_SIZE;
|
||||
status = sdmmc_execute_command(CMD_SET_BLOCKLEN, MMC_SECTOR_SIZE, 0);
|
||||
if (status != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @defgroup SDMMC_Public_Functions
|
||||
* @ingroup SDMMC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Function to enumerate the SD/MMC/SDHC/MMC+ cards
|
||||
* @param[in] evsetup_cb Pointer to event setup function callback
|
||||
* @param[in] waitfunc_cb Pointer to wait function callback
|
||||
* @param[in] msdelay_func Pointer to function that delays
|
||||
* @param[in] pcardinfo Pointer to pre-allocated card info structure
|
||||
* @return 1 if a card is acquired, otherwise 0
|
||||
**********************************************************************/
|
||||
int32_t sdmmc_acquire(MCI_EVSETUP_FUNC_T evsetup_cb,
|
||||
MCI_WAIT_CB_FUNC_T waitfunc_cb, MCI_MSDELAY_FUNC_T msdelay_func,
|
||||
struct _mci_card_struct *pcardinfo)
|
||||
{
|
||||
int32_t status;
|
||||
int32_t tries = 0;
|
||||
uint32_t ocr = OCR_VOLTAGE_RANGE_MSK;
|
||||
uint32_t r;
|
||||
int32_t state = 0;
|
||||
uint32_t command = 0;
|
||||
|
||||
g_card_info = pcardinfo;
|
||||
|
||||
/* Make sure callbacks are valid */
|
||||
if ((waitfunc_cb == NULL) || (msdelay_func == NULL) ||
|
||||
(evsetup_cb == NULL))
|
||||
return 0;
|
||||
|
||||
sdmmc_evsetup_cb = evsetup_cb;
|
||||
sdmmc_wait_cb = waitfunc_cb;
|
||||
sdmmc_msdelay_cb = msdelay_func;
|
||||
|
||||
/* clear card struct */
|
||||
memset(g_card_info, 0, sizeof(*g_card_info));
|
||||
|
||||
/* clear card type */
|
||||
LPC_SDMMC->CTYPE = 0;
|
||||
|
||||
/* set high speed for the card as 20MHz */
|
||||
g_card_info->speed = MMC_MAX_CLOCK;
|
||||
|
||||
status = sdmmc_execute_command(CMD_IDLE, 0, MCI_INT_CMD_DONE);
|
||||
|
||||
while (state < 100)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case 0: /* Setup for SD */
|
||||
/* check if it is SDHC card */
|
||||
status = sdmmc_execute_command( CMD_SD_SEND_IF_COND, SD_SEND_IF_ARG, 0);
|
||||
if (!(status & MCI_INT_RTO))
|
||||
{
|
||||
/* check response has same echo pattern */
|
||||
if ((g_card_info->response[0] & SD_SEND_IF_ECHO_MSK) == SD_SEND_IF_RESP)
|
||||
ocr |= OCR_HC_CCS;
|
||||
}
|
||||
|
||||
++state;
|
||||
command = CMD_SD_OP_COND;
|
||||
tries = INIT_OP_RETRIES;
|
||||
|
||||
/* assume SD card */
|
||||
g_card_info->card_type |= CARD_TYPE_SD;
|
||||
g_card_info->speed = SD_MAX_CLOCK;
|
||||
break;
|
||||
|
||||
case 10: /* Setup for MMC */
|
||||
/* start fresh for MMC crds */
|
||||
g_card_info->card_type &= ~CARD_TYPE_SD;
|
||||
status = sdmmc_execute_command(CMD_IDLE, 0, MCI_INT_CMD_DONE);
|
||||
command = CMD_MMC_OP_COND;
|
||||
tries = INIT_OP_RETRIES;
|
||||
ocr |= OCR_HC_CCS;
|
||||
++state;
|
||||
|
||||
/* for MMC cards high speed is 20MHz */
|
||||
g_card_info->speed = MMC_MAX_CLOCK;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case 11:
|
||||
status = sdmmc_execute_command(command, 0, 0);
|
||||
if (status & MCI_INT_RTO)
|
||||
state += 9; /* Mode unavailable */
|
||||
else
|
||||
++state;
|
||||
break;
|
||||
|
||||
case 2: /* Initial OCR check */
|
||||
case 12:
|
||||
ocr = g_card_info->response[0] | (ocr & OCR_HC_CCS);
|
||||
if (ocr & OCR_ALL_READY)
|
||||
++state;
|
||||
else
|
||||
state += 2;
|
||||
break;
|
||||
|
||||
case 3: /* Initial wait for OCR clear */
|
||||
case 13:
|
||||
while ((ocr & OCR_ALL_READY) && --tries > 0)
|
||||
{
|
||||
sdmmc_msdelay_cb(MS_ACQUIRE_DELAY);
|
||||
status = sdmmc_execute_command(command, 0, 0);
|
||||
ocr = g_card_info->response[0] | (ocr & OCR_HC_CCS);
|
||||
}
|
||||
if (ocr & OCR_ALL_READY)
|
||||
state += 7;
|
||||
else
|
||||
++state;
|
||||
break;
|
||||
|
||||
case 14:
|
||||
/* for MMC cards set high capacity bit */
|
||||
ocr |= OCR_HC_CCS;
|
||||
case 4: /* Assign OCR */
|
||||
tries = SET_OP_RETRIES;
|
||||
ocr &= OCR_VOLTAGE_RANGE_MSK | OCR_HC_CCS; /* Mask for the bits we care about */
|
||||
do
|
||||
{
|
||||
sdmmc_msdelay_cb(MS_ACQUIRE_DELAY);
|
||||
status = sdmmc_execute_command(command, ocr, 0);
|
||||
r = g_card_info->response[0];
|
||||
} while (!(r & OCR_ALL_READY) && --tries > 0);
|
||||
|
||||
if (r & OCR_ALL_READY)
|
||||
{
|
||||
/* is it high capacity card */
|
||||
g_card_info->card_type |= (r & OCR_HC_CCS);
|
||||
++state;
|
||||
}
|
||||
else
|
||||
state += 6;
|
||||
break;
|
||||
|
||||
case 5: /* CID polling */
|
||||
case 15:
|
||||
status = sdmmc_execute_command(CMD_ALL_SEND_CID, 0, 0);
|
||||
memcpy(&g_card_info->cid, &g_card_info->response[0], 16);
|
||||
++state;
|
||||
break;
|
||||
|
||||
case 6: /* RCA send, for SD get RCA */
|
||||
status = sdmmc_execute_command(CMD_SD_SEND_RCA, 0, 0);
|
||||
g_card_info->rca = (g_card_info->response[0]) >> 16;
|
||||
++state;
|
||||
break;
|
||||
|
||||
case 16: /* RCA assignment for MMC set to 1 */
|
||||
g_card_info->rca = 1;
|
||||
status = sdmmc_execute_command(CMD_MMC_SET_RCA, g_card_info->rca << 16, 0);
|
||||
++state;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
case 17:
|
||||
status = sdmmc_execute_command(CMD_SEND_CSD, g_card_info->rca << 16, 0);
|
||||
memcpy(&g_card_info->csd, &g_card_info->response[0], 16);
|
||||
state = 100;
|
||||
break;
|
||||
|
||||
default:
|
||||
state += 100; /* break from while loop */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute card size, block size and no. of blocks
|
||||
based on CSD response recived. */
|
||||
if (prv_card_acquired()) {
|
||||
prv_process_csd();
|
||||
|
||||
/* Setup card data width and block size (once) */
|
||||
if (prv_set_trans_state() != 0)
|
||||
return 0;
|
||||
if (prv_set_card_params() != 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return prv_card_acquired();
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get card's current state (idle, transfer, program, etc.)
|
||||
* @param[in] None
|
||||
* @return Current transfer state (0 -
|
||||
**********************************************************************/
|
||||
int32_t sdmmc_get_state(void)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
/* get current state of the card */
|
||||
status = sdmmc_execute_command(CMD_SEND_STATUS, g_card_info->rca << 16, 0);
|
||||
if (status & MCI_INT_RTO)
|
||||
return -1;
|
||||
|
||||
/* check card state in response */
|
||||
return (int32_t) R1_CURRENT_STATE(g_card_info->response[0]);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get the device size of SD/MMC card
|
||||
* @param[in] None
|
||||
* @return Device size
|
||||
**********************************************************************/
|
||||
int32_t sdmmc_get_device_size(void)
|
||||
{
|
||||
return g_card_info->device_size;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Performs the read of data from the SD/MMC card
|
||||
* @param[in] buffer Pointer to data buffer to copy to
|
||||
* @param[in] start_block Start block number
|
||||
* @param[in] end_block End block number
|
||||
* @return Bytes read, or 0 on error
|
||||
**********************************************************************/
|
||||
int32_t sdmmc_read_blocks(void* buffer, int32_t start_block,
|
||||
int32_t end_block)
|
||||
{
|
||||
int32_t cbRead = (end_block - start_block + 1) * MMC_SECTOR_SIZE;
|
||||
int32_t status = 0;
|
||||
int32_t index;
|
||||
|
||||
/* if card is not acquired return immediately */
|
||||
if ((end_block < start_block) || (start_block < 0) ||
|
||||
(end_block > g_card_info->blocknr))
|
||||
return 0;
|
||||
|
||||
/* put card in trans state */
|
||||
if (prv_set_trans_state() != 0)
|
||||
return 0;
|
||||
|
||||
/* set number of bytes to read */
|
||||
LPC_SDMMC->BYTCNT = cbRead;
|
||||
|
||||
/* if high capacity card use block indexing */
|
||||
if (g_card_info->card_type & CARD_TYPE_HC)
|
||||
index = start_block;
|
||||
else/*fix at 512 bytes*/
|
||||
index = start_block << 9;//\* g_card_info->block_len;
|
||||
|
||||
sdif_dma_setup((uint32_t) buffer, cbRead);
|
||||
|
||||
/* Select single or multiple read based on number of blocks */
|
||||
if (end_block == start_block)
|
||||
status = sdmmc_execute_command(CMD_READ_SINGLE,
|
||||
index, 0 | MCI_INT_DATA_OVER);
|
||||
else
|
||||
status = sdmmc_execute_command(CMD_READ_MULTIPLE,
|
||||
index, 0 | MCI_INT_DATA_OVER);
|
||||
|
||||
if (status != 0)
|
||||
cbRead = 0;
|
||||
/*Wait for card program to finish*/
|
||||
while (sdmmc_get_state() != SDMMC_TRAN_ST);
|
||||
|
||||
return cbRead;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Performs write of data to the SD/MMC card
|
||||
* @param[in] buffer Pointer to data buffer to copy to
|
||||
* @param[in] start_block Start block number
|
||||
* @param[in] end_block End block number
|
||||
* @return Number of bytes actually written, or 0 on error
|
||||
**********************************************************************/
|
||||
int32_t sdmmc_write_blocks(void* buffer,
|
||||
int32_t start_block,
|
||||
int32_t end_block)
|
||||
{
|
||||
int32_t cbWrote = (end_block - start_block + 1) * MMC_SECTOR_SIZE;
|
||||
int32_t status;
|
||||
int32_t index;
|
||||
|
||||
/* if card is not acquired return immediately */
|
||||
if ((end_block < start_block) || (start_block < 0) ||
|
||||
(end_block > g_card_info->blocknr))
|
||||
return 0;
|
||||
|
||||
/*Wait for card program to finish*/
|
||||
while (sdmmc_get_state() != SDMMC_TRAN_ST);
|
||||
|
||||
/* put card in trans state */
|
||||
if (prv_set_trans_state() != 0)
|
||||
return 0;
|
||||
|
||||
/* set number of bytes to write */
|
||||
LPC_SDMMC->BYTCNT = cbWrote;
|
||||
|
||||
/* if high capacity card use block indexing */
|
||||
if (g_card_info->card_type & CARD_TYPE_HC)
|
||||
index = start_block;
|
||||
else/*fix at 512 bytes*/
|
||||
index = start_block << 9;//* g_card_info->block_len;
|
||||
|
||||
sdif_dma_setup((uint32_t) buffer, cbWrote);
|
||||
|
||||
/*Wait for card program to finish*/
|
||||
while (sdmmc_get_state() != SDMMC_TRAN_ST);
|
||||
|
||||
/* Select single or multiple write based on number of blocks */
|
||||
if (end_block == start_block)
|
||||
status = sdmmc_execute_command(CMD_WRITE_SINGLE,
|
||||
index, 0 | MCI_INT_DATA_OVER);
|
||||
else
|
||||
status = sdmmc_execute_command(CMD_WRITE_MULTIPLE, index,
|
||||
0 | MCI_INT_DATA_OVER);
|
||||
|
||||
if (status != 0)
|
||||
cbWrote = 0;
|
||||
|
||||
return cbWrote;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _SDMMC */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
@@ -0,0 +1,650 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_ssp.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_ssp.c
|
||||
* @brief Contains all functions support for SSP firmware library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup SSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_ssp.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
|
||||
#ifdef _SSP
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup SSP_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup SSP_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Initializes the SSPx peripheral according to the specified
|
||||
* parameters in the SSP_ConfigStruct.
|
||||
* @param[in] SSPx SSP peripheral selected, should be:
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @param[in] SSP_ConfigStruct Pointer to a SSP_CFG_Type structure that
|
||||
* contains the configuration information for the specified
|
||||
* SSP peripheral.
|
||||
* @return None
|
||||
*********************************************************************/
|
||||
void SSP_Init(LPC_SSPn_Type *SSPx, SSP_CFG_Type *SSP_ConfigStruct)
|
||||
{
|
||||
uint32_t tmp;
|
||||
uint32_t prescale, cr0_div, cmp_clk;
|
||||
uint64_t ssp_clk;
|
||||
|
||||
CHECK_PARAM(PARAM_SSPx(SSPx));
|
||||
|
||||
if(SSPx == LPC_SSP0) {
|
||||
/* Set up clock and power for SSP0 module */
|
||||
//LPC_CGU->BASE_SSP0_CLK = (SRC_PL160M_0<<24) | (1<<11);
|
||||
CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_SSP0);
|
||||
} else if(SSPx == LPC_SSP1) {
|
||||
/* Set up clock and power for SSP1 module */
|
||||
//LPC_CGU->BASE_SSP1_CLK = (SRC_PL160M_0<<24) | (1<<11);
|
||||
CGU_EntityConnect(CGU_CLKSRC_PLL1, CGU_BASE_SSP1);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Configure SSP, interrupt is disable, LoopBack mode is disable,
|
||||
* SSP is disable, Slave output is disable as default
|
||||
*/
|
||||
tmp = ((SSP_ConfigStruct->CPHA) | (SSP_ConfigStruct->CPOL) \
|
||||
| (SSP_ConfigStruct->FrameFormat) | (SSP_ConfigStruct->Databit))
|
||||
& SSP_CR0_BITMASK;
|
||||
// write back to SSP control register
|
||||
SSPx->CR0 = tmp;
|
||||
|
||||
tmp = SSP_ConfigStruct->Mode & SSP_CR1_BITMASK;
|
||||
// Write back to CR1
|
||||
SSPx->CR1 = tmp;
|
||||
|
||||
// Set clock rate for SSP peripheral
|
||||
if(SSPx == LPC_SSP0)
|
||||
ssp_clk = CGU_GetPCLKFrequency(CGU_PERIPHERAL_SSP0);
|
||||
else
|
||||
ssp_clk = CGU_GetPCLKFrequency(CGU_PERIPHERAL_SSP1);
|
||||
cr0_div = 0;
|
||||
cmp_clk = 0xFFFFFFFF;
|
||||
prescale = 2;
|
||||
while (cmp_clk > SSP_ConfigStruct->ClockRate)
|
||||
{
|
||||
cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);
|
||||
if (cmp_clk > SSP_ConfigStruct->ClockRate)
|
||||
{
|
||||
cr0_div++;
|
||||
if (cr0_div > 0xFF)
|
||||
{
|
||||
cr0_div = 0;
|
||||
prescale += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write computed prescaler and divider back to register */
|
||||
SSPx->CR0 &= (~SSP_CR0_SCR(0xFF)) & SSP_CR0_BITMASK;
|
||||
SSPx->CR0 |= (SSP_CR0_SCR(cr0_div)) & SSP_CR0_BITMASK;
|
||||
SSPx->CPSR = prescale & SSP_CPSR_BITMASK;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief De-initializes the SSPx peripheral registers to their
|
||||
* default reset values.
|
||||
* @param[in] SSPx SSP peripheral selected, should be:
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void SSP_DeInit(LPC_SSPn_Type* SSPx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SSPx(SSPx));
|
||||
|
||||
/* Disable SSP operation*/
|
||||
SSPx->CR1 &= (~SSP_CR1_SSP_EN) & SSP_CR1_BITMASK;
|
||||
}
|
||||
|
||||
/*****************************************************************************//**
|
||||
* @brief Get data size bit selected
|
||||
* @param[in] SSPx pointer to LPC_SSPn_Type structure, should be:
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @return Data size, could be:
|
||||
* - SSP_DATABIT_4 :4 bit transfer
|
||||
* - SSP_DATABIT_5 :5 bit transfer
|
||||
* ...
|
||||
* - SSP_DATABIT_16 :16 bit transfer
|
||||
*******************************************************************************/
|
||||
uint8_t SSP_GetDataSize(LPC_SSPn_Type* SSPx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SSPx(SSPx));
|
||||
return (SSPx->CR0 & (0xF));
|
||||
}
|
||||
|
||||
/*****************************************************************************//**
|
||||
* @brief Fills each SSP_InitStruct member with its default value:
|
||||
* - CPHA = SSP_CPHA_FIRST
|
||||
* - CPOL = SSP_CPOL_HI
|
||||
* - ClockRate = 1000000
|
||||
* - Databit = SSP_DATABIT_8
|
||||
* - Mode = SSP_MASTER_MODE
|
||||
* - FrameFormat = SSP_FRAME_SSP
|
||||
* @param[in] SSP_InitStruct Pointer to a SSP_CFG_Type structure which will be
|
||||
* initialized.
|
||||
* @return None
|
||||
*******************************************************************************/
|
||||
void SSP_ConfigStructInit(SSP_CFG_Type *SSP_InitStruct)
|
||||
{
|
||||
SSP_InitStruct->CPHA = SSP_CPHA_FIRST;
|
||||
SSP_InitStruct->CPOL = SSP_CPOL_HI;
|
||||
SSP_InitStruct->ClockRate = 100000;
|
||||
SSP_InitStruct->Databit = SSP_DATABIT_8;
|
||||
SSP_InitStruct->Mode = SSP_MASTER_MODE;
|
||||
SSP_InitStruct->FrameFormat = SSP_FRAME_SPI;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable or disable SSP peripheral's operation
|
||||
* @param[in] SSPx SSP peripheral, should be:
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @param[in] NewState New State of SSPx peripheral's operation, should be:
|
||||
* - ENABLE
|
||||
* - DISABLE
|
||||
* @return none
|
||||
**********************************************************************/
|
||||
void SSP_Cmd(LPC_SSPn_Type* SSPx, FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SSPx(SSPx));
|
||||
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
|
||||
|
||||
if (NewState == ENABLE)
|
||||
{
|
||||
SSPx->CR1 |= SSP_CR1_SSP_EN;
|
||||
}
|
||||
else
|
||||
{
|
||||
SSPx->CR1 &= (~SSP_CR1_SSP_EN) & SSP_CR1_BITMASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable or disable Loop Back mode function in SSP peripheral
|
||||
* @param[in] SSPx SSP peripheral selected, should be:
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @param[in] NewState New State of Loop Back mode, should be:
|
||||
* - ENABLE
|
||||
* - DISABLE
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void SSP_LoopBackCmd(LPC_SSPn_Type* SSPx, FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SSPx(SSPx));
|
||||
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
|
||||
|
||||
if (NewState == ENABLE)
|
||||
{
|
||||
SSPx->CR1 |= SSP_CR1_LBM_EN;
|
||||
}
|
||||
else
|
||||
{
|
||||
SSPx->CR1 &= (~SSP_CR1_LBM_EN) & SSP_CR1_BITMASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable or disable Slave Output function in SSP peripheral
|
||||
* @param[in] SSPx SSP peripheral selected, should be:
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @param[in] NewState New State of Slave Output function, should be:
|
||||
* - ENABLE :Slave Output in normal operation
|
||||
* - DISABLE :Slave Output is disabled. This blocks
|
||||
* SSP controller from driving the transmit data line (MISO)
|
||||
* Note: This function is available when SSP peripheral in Slave mode
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void SSP_SlaveOutputCmd(LPC_SSPn_Type* SSPx, FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SSPx(SSPx));
|
||||
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
|
||||
|
||||
if (NewState == ENABLE)
|
||||
{
|
||||
SSPx->CR1 &= (~SSP_CR1_SO_DISABLE) & SSP_CR1_BITMASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
SSPx->CR1 |= SSP_CR1_SO_DISABLE;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Transmit a single data through SSPx peripheral
|
||||
* @param[in] SSPx SSP peripheral selected, should be:
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @param[in] Data Data to transmit (must be 16 or 8-bit long, this
|
||||
* depend on SSP data bit number configured)
|
||||
* @return none
|
||||
**********************************************************************/
|
||||
void SSP_SendData(LPC_SSPn_Type* SSPx, uint16_t Data)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SSPx(SSPx));
|
||||
|
||||
SSPx->DR = SSP_DR_BITMASK(Data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Receive a single data from SSPx peripheral
|
||||
* @param[in] SSPx SSP peripheral selected, should be
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @return Data received (16-bit long)
|
||||
**********************************************************************/
|
||||
uint16_t SSP_ReceiveData(LPC_SSPn_Type* SSPx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SSPx(SSPx));
|
||||
|
||||
return ((uint16_t) (SSP_DR_BITMASK(SSPx->DR)));
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief SSP Read write data function
|
||||
* @param[in] SSPx Pointer to SSP peripheral, should be
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @param[in] dataCfg Pointer to a SSP_DATA_SETUP_Type structure that
|
||||
* contains specified information about transmit data
|
||||
* configuration.
|
||||
* @param[in] xfType Transfer type, should be:
|
||||
* - SSP_TRANSFER_POLLING :Polling mode
|
||||
* - SSP_TRANSFER_INTERRUPT :Interrupt mode
|
||||
* @return Actual Data length has been transferred in polling mode.
|
||||
* In interrupt mode, always return (0)
|
||||
* Return (-1) if error.
|
||||
* Note: This function can be used in both master and slave mode.
|
||||
***********************************************************************/
|
||||
int32_t SSP_ReadWrite (LPC_SSPn_Type *SSPx, SSP_DATA_SETUP_Type *dataCfg, \
|
||||
SSP_TRANSFER_Type xfType)
|
||||
{
|
||||
uint8_t *rdata8;
|
||||
uint8_t *wdata8;
|
||||
uint16_t *rdata16;
|
||||
uint16_t *wdata16;
|
||||
uint32_t stat;
|
||||
uint32_t tmp;
|
||||
int32_t dataword;
|
||||
|
||||
dataCfg->rx_cnt = 0;
|
||||
dataCfg->tx_cnt = 0;
|
||||
dataCfg->status = 0;
|
||||
|
||||
|
||||
/* Clear all remaining data in RX FIFO */
|
||||
while (SSPx->SR & SSP_SR_RNE){
|
||||
tmp = (uint32_t) SSP_ReceiveData(SSPx);
|
||||
}
|
||||
|
||||
// Clear status
|
||||
SSPx->ICR = SSP_ICR_BITMASK;
|
||||
if(SSP_GetDataSize(SSPx) > SSP_DATABIT_8)
|
||||
dataword = 1;
|
||||
else dataword = 0;
|
||||
|
||||
// Polling mode ----------------------------------------------------------------------
|
||||
if (xfType == SSP_TRANSFER_POLLING){
|
||||
if (dataword == 0){
|
||||
rdata8 = (uint8_t *)dataCfg->rx_data;
|
||||
wdata8 = (uint8_t *)dataCfg->tx_data;
|
||||
} else {
|
||||
rdata16 = (uint16_t *)dataCfg->rx_data;
|
||||
wdata16 = (uint16_t *)dataCfg->tx_data;
|
||||
}
|
||||
while ((dataCfg->tx_cnt != dataCfg->length) || (dataCfg->rx_cnt != dataCfg->length)){
|
||||
if ((SSPx->SR & SSP_SR_TNF) && (dataCfg->tx_cnt != dataCfg->length)){
|
||||
// Write data to buffer
|
||||
if(dataCfg->tx_data == NULL){
|
||||
if (dataword == 0){
|
||||
SSP_SendData(SSPx, 0xFF);
|
||||
dataCfg->tx_cnt++;
|
||||
} else {
|
||||
SSP_SendData(SSPx, 0xFFFF);
|
||||
dataCfg->tx_cnt += 2;
|
||||
}
|
||||
} else {
|
||||
if (dataword == 0){
|
||||
SSP_SendData(SSPx, *wdata8);
|
||||
wdata8++;
|
||||
dataCfg->tx_cnt++;
|
||||
} else {
|
||||
SSP_SendData(SSPx, *wdata16);
|
||||
wdata16++;
|
||||
dataCfg->tx_cnt += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check overrun error
|
||||
if ((stat = SSPx->RIS) & SSP_RIS_ROR){
|
||||
// save status and return
|
||||
dataCfg->status = stat | SSP_STAT_ERROR;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// Check for any data available in RX FIFO
|
||||
while ((SSPx->SR & SSP_SR_RNE) && (dataCfg->rx_cnt != dataCfg->length)){
|
||||
// Read data from SSP data
|
||||
tmp = SSP_ReceiveData(SSPx);
|
||||
|
||||
// Store data to destination
|
||||
if (dataCfg->rx_data != NULL)
|
||||
{
|
||||
if (dataword == 0){
|
||||
*(rdata8) = (uint8_t) tmp;
|
||||
rdata8++;
|
||||
} else {
|
||||
*(rdata16) = (uint16_t) tmp;
|
||||
rdata16++;
|
||||
}
|
||||
}
|
||||
// Increase counter
|
||||
if (dataword == 0){
|
||||
dataCfg->rx_cnt++;
|
||||
} else {
|
||||
dataCfg->rx_cnt += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// save status
|
||||
dataCfg->status = SSP_STAT_DONE;
|
||||
|
||||
if (dataCfg->tx_data != NULL){
|
||||
return dataCfg->tx_cnt;
|
||||
} else if (dataCfg->rx_data != NULL){
|
||||
return dataCfg->rx_cnt;
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
// Interrupt mode ----------------------------------------------------------------------
|
||||
else if (xfType == SSP_TRANSFER_INTERRUPT){
|
||||
|
||||
while ((SSPx->SR & SSP_SR_TNF) && (dataCfg->tx_cnt != dataCfg->length)){
|
||||
// Write data to buffer
|
||||
if(dataCfg->tx_data == NULL){
|
||||
if (dataword == 0){
|
||||
SSP_SendData(SSPx, 0xFF);
|
||||
dataCfg->tx_cnt++;
|
||||
} else {
|
||||
SSP_SendData(SSPx, 0xFFFF);
|
||||
dataCfg->tx_cnt += 2;
|
||||
}
|
||||
} else {
|
||||
if (dataword == 0){
|
||||
SSP_SendData(SSPx, (*(uint8_t *)((uint32_t)dataCfg->tx_data + dataCfg->tx_cnt)));
|
||||
dataCfg->tx_cnt++;
|
||||
} else {
|
||||
SSP_SendData(SSPx, (*(uint16_t *)((uint32_t)dataCfg->tx_data + dataCfg->tx_cnt)));
|
||||
dataCfg->tx_cnt += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Check error
|
||||
if ((stat = SSPx->RIS) & SSP_RIS_ROR){
|
||||
// save status and return
|
||||
dataCfg->status = stat | SSP_STAT_ERROR;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// Check for any data available in RX FIFO
|
||||
while ((SSPx->SR & SSP_SR_RNE) && (dataCfg->rx_cnt != dataCfg->length)){
|
||||
// Read data from SSP data
|
||||
tmp = SSP_ReceiveData(SSPx);
|
||||
|
||||
// Store data to destination
|
||||
if (dataCfg->rx_data != NULL)
|
||||
{
|
||||
if (dataword == 0){
|
||||
*(uint8_t *)((uint32_t)dataCfg->rx_data + dataCfg->rx_cnt) = (uint8_t) tmp;
|
||||
} else {
|
||||
*(uint16_t *)((uint32_t)dataCfg->rx_data + dataCfg->rx_cnt) = (uint16_t) tmp;
|
||||
}
|
||||
}
|
||||
// Increase counter
|
||||
if (dataword == 0){
|
||||
dataCfg->rx_cnt++;
|
||||
} else {
|
||||
dataCfg->rx_cnt += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there more data to sent or receive
|
||||
if ((dataCfg->rx_cnt != dataCfg->length) || (dataCfg->tx_cnt != dataCfg->length)){
|
||||
// Enable all interrupt
|
||||
SSPx->IMSC = SSP_IMSC_BITMASK;
|
||||
} else {
|
||||
// Save status
|
||||
dataCfg->status = SSP_STAT_DONE;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Checks whether the specified SSP status flag is set or not
|
||||
* @param[in] SSPx SSP peripheral selected, should be:
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @param[in] FlagType Type of flag to check status, should be:
|
||||
* - SSP_STAT_TXFIFO_EMPTY :TX FIFO is empty
|
||||
* - SSP_STAT_TXFIFO_NOTFULL :TX FIFO is not full
|
||||
* - SSP_STAT_RXFIFO_NOTEMPTY :RX FIFO is not empty
|
||||
* - SSP_STAT_RXFIFO_FULL :RX FIFO is full
|
||||
* - SSP_STAT_BUSY :SSP peripheral is busy
|
||||
* @return New State of specified SSP status flag
|
||||
**********************************************************************/
|
||||
FlagStatus SSP_GetStatus(LPC_SSPn_Type* SSPx, uint32_t FlagType)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SSPx(SSPx));
|
||||
CHECK_PARAM(PARAM_SSP_STAT(FlagType));
|
||||
|
||||
return ((SSPx->SR & FlagType) ? SET : RESET);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable or disable specified interrupt type in SSP peripheral
|
||||
* @param[in] SSPx SSP peripheral selected, should be:
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @param[in] IntType Interrupt type in SSP peripheral, should be:
|
||||
* - SSP_INTCFG_ROR :Receive Overrun interrupt
|
||||
* - SSP_INTCFG_RT :Receive Time out interrupt
|
||||
* - SSP_INTCFG_RX :RX FIFO is at least half full interrupt
|
||||
* - SSP_INTCFG_TX :TX FIFO is at least half empty interrupt
|
||||
* @param[in] NewState New State of specified interrupt type, should be:
|
||||
* - ENABLE :Enable this interrupt type
|
||||
* - DISABLE :Disable this interrupt type
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void SSP_IntConfig(LPC_SSPn_Type *SSPx, uint32_t IntType, FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SSPx(SSPx));
|
||||
CHECK_PARAM(PARAM_SSP_INTCFG(IntType));
|
||||
|
||||
if (NewState == ENABLE)
|
||||
{
|
||||
SSPx->IMSC |= IntType;
|
||||
}
|
||||
else
|
||||
{
|
||||
SSPx->IMSC &= (~IntType) & SSP_IMSC_BITMASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Check whether the specified Raw interrupt status flag is
|
||||
* set or not
|
||||
* @param[in] SSPx SSP peripheral selected, should be:
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @param[in] RawIntType Raw Interrupt Type, should be:
|
||||
* - SSP_INTSTAT_RAW_ROR :Receive Overrun interrupt
|
||||
* - SSP_INTSTAT_RAW_RT :Receive Time out interrupt
|
||||
* - SSP_INTSTAT_RAW_RX :RX FIFO is at least half full interrupt
|
||||
* - SSP_INTSTAT_RAW_TX :TX FIFO is at least half empty interrupt
|
||||
* @return New State of specified Raw interrupt status flag in SSP peripheral
|
||||
* Note: Enabling/Disabling specified interrupt in SSP peripheral does not
|
||||
* effect to Raw Interrupt Status flag.
|
||||
**********************************************************************/
|
||||
IntStatus SSP_GetRawIntStatus(LPC_SSPn_Type *SSPx, uint32_t RawIntType)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SSPx(SSPx));
|
||||
CHECK_PARAM(PARAM_SSP_INTSTAT_RAW(RawIntType));
|
||||
|
||||
return ((SSPx->RIS & RawIntType) ? SET : RESET);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Check whether the specified interrupt status flag is
|
||||
* set or not
|
||||
* @param[in] SSPx SSP peripheral selected, should be:
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @param[in] IntType Raw Interrupt Type, should be:
|
||||
* - SSP_INTSTAT_ROR :Receive Overrun interrupt
|
||||
* - SSP_INTSTAT_RT :Receive Time out interrupt
|
||||
* - SSP_INTSTAT_RX :RX FIFO is at least half full interrupt
|
||||
* - SSP_INTSTAT_TX :TX FIFO is at least half empty interrupt
|
||||
* @return New State of specified interrupt status flag in SSP peripheral
|
||||
* Note: Enabling/Disabling specified interrupt in SSP peripheral effects
|
||||
* to Interrupt Status flag.
|
||||
**********************************************************************/
|
||||
IntStatus SSP_GetIntStatus (LPC_SSPn_Type *SSPx, uint32_t IntType)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SSPx(SSPx));
|
||||
CHECK_PARAM(PARAM_SSP_INTSTAT(IntType));
|
||||
|
||||
return ((SSPx->MIS & IntType) ? SET :RESET);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Clear specified interrupt pending in SSP peripheral
|
||||
* @param[in] SSPx SSP peripheral selected, should be:
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @param[in] IntType Interrupt pending to clear, should be:
|
||||
* - SSP_INTCLR_ROR :clears the "frame was received when
|
||||
* RxFIFO was full" interrupt.
|
||||
* - SSP_INTCLR_RT :clears the "Rx FIFO was not empty and
|
||||
* has not been read for a timeout period" interrupt.
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void SSP_ClearIntPending(LPC_SSPn_Type *SSPx, uint32_t IntType)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SSPx(SSPx));
|
||||
CHECK_PARAM(PARAM_SSP_INTCLR(IntType));
|
||||
|
||||
SSPx->ICR = IntType;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable/Disable DMA function for SSP peripheral
|
||||
* @param[in] SSPx SSP peripheral selected, should be:
|
||||
* - LPC_SSP0 :SSP0 peripheral
|
||||
* - LPC_SSP1 :SSP1 peripheral
|
||||
* @param[in] DMAMode Type of DMA, should be:
|
||||
* - SSP_DMA_TX :DMA for the transmit FIFO
|
||||
* - SSP_DMA_RX :DMA for the Receive FIFO
|
||||
* @param[in] NewState New State of DMA function on SSP peripheral,
|
||||
* should be:
|
||||
* - ENALBE :Enable this function
|
||||
* - DISABLE :Disable this function
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void SSP_DMACmd(LPC_SSPn_Type *SSPx, uint32_t DMAMode, FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_SSPx(SSPx));
|
||||
CHECK_PARAM(PARAM_SSP_DMA(DMAMode));
|
||||
CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState));
|
||||
|
||||
if (NewState == ENABLE)
|
||||
{
|
||||
SSPx->DMACR |= DMAMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
SSPx->DMACR &= (~DMAMode) & SSP_DMA_BITMASK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _SSP */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* --------------------------------- End Of File ------------------------------ */
|
||||
@@ -0,0 +1,616 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_timer.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_timer.c
|
||||
* @brief Contains all functions support for Timer firmware library on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup TIMER
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_timer.h"
|
||||
#include "lpc43xx_cgu.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
#ifdef _TIM
|
||||
|
||||
/* Private Functions ---------------------------------------------------------- */
|
||||
|
||||
static uint32_t getPClock (uint32_t timernum);
|
||||
static uint32_t converUSecToVal (uint32_t timernum, uint32_t usec);
|
||||
static uint32_t converPtrToTimeNum (LPC_TIMERn_Type *TIMx);
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get peripheral clock of each timer controller
|
||||
* @param[in] timernum Timer number, should be: 0..3
|
||||
* @return Peripheral clock of timer
|
||||
**********************************************************************/
|
||||
extern uint32_t M3Frequency;
|
||||
static uint32_t getPClock (uint32_t timernum)
|
||||
{
|
||||
uint32_t clkdlycnt;
|
||||
switch (timernum)
|
||||
{
|
||||
case 0:
|
||||
clkdlycnt = /*CGU_GetPCLK (CGU_PCLKSEL_TIMER0)*/ CGU_GetPCLKFrequency(CGU_PERIPHERAL_TIMER0);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
clkdlycnt = /*CGU_GetPCLK (CGU_PCLKSEL_TIMER1)*/ CGU_GetPCLKFrequency(CGU_PERIPHERAL_TIMER1);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
clkdlycnt = /*CGU_GetPCLK (CGU_PCLKSEL_TIMER2)*/ CGU_GetPCLKFrequency(CGU_PERIPHERAL_TIMER2);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
clkdlycnt = /*CGU_GetPCLK (CGU_PCLKSEL_TIMER3)*/ CGU_GetPCLKFrequency(CGU_PERIPHERAL_TIMER3);
|
||||
break;
|
||||
}
|
||||
return clkdlycnt;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Convert a time to a timer count value
|
||||
* @param[in] timernum Timer number, should be: 0..3
|
||||
* @param[in] usec Time in microseconds
|
||||
* @return The number of required clock ticks to give the time delay
|
||||
**********************************************************************/
|
||||
uint32_t converUSecToVal (uint32_t timernum, uint32_t usec)
|
||||
{
|
||||
uint64_t clkdlycnt;
|
||||
|
||||
// Get Pclock of timer
|
||||
clkdlycnt = (uint64_t) getPClock(timernum);
|
||||
|
||||
clkdlycnt = (clkdlycnt * usec) / 1000000;
|
||||
return (uint32_t) clkdlycnt;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Convert a timer register pointer to a timer number
|
||||
* @param[in] TIMx Pointer to LPC_TIMERn_Type, should be:
|
||||
* - LPC_TIM0 :TIMER0 peripheral
|
||||
* - LPC_TIM1 :TIMER1 peripheral
|
||||
* - LPC_TIM2 :TIMER2 peripheral
|
||||
* - LPC_TIM3 :TIMER3 peripheral
|
||||
* @return The timer number (0 to 3) or -1 if register pointer is bad
|
||||
**********************************************************************/
|
||||
uint32_t converPtrToTimeNum (LPC_TIMERn_Type *TIMx)
|
||||
{
|
||||
uint32_t tnum = 0xFFFFFFFF;
|
||||
|
||||
if (TIMx == LPC_TIMER0)
|
||||
{
|
||||
tnum = 0;
|
||||
}
|
||||
else if (TIMx == LPC_TIMER1)
|
||||
{
|
||||
tnum = 1;
|
||||
}
|
||||
else if (TIMx == LPC_TIMER2)
|
||||
{
|
||||
tnum = 2;
|
||||
}
|
||||
else if (TIMx == LPC_TIMER3)
|
||||
{
|
||||
tnum = 3;
|
||||
}
|
||||
|
||||
return tnum;
|
||||
}
|
||||
|
||||
/* End of Private Functions ---------------------------------------------------- */
|
||||
|
||||
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup TIM_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Get Interrupt Status
|
||||
* @param[in] TIMx Timer selection, should be:
|
||||
* - LPC_TIM0 :TIMER0 peripheral
|
||||
* - LPC_TIM1 :TIMER1 peripheral
|
||||
* - LPC_TIM2 :TIMER2 peripheral
|
||||
* - LPC_TIM3 :TIMER3 peripheral
|
||||
* @param[in] IntFlag: interrupt type, should be:
|
||||
* - TIM_MR0_INT :Interrupt for Match channel 0
|
||||
* - TIM_MR1_INT :Interrupt for Match channel 1
|
||||
* - TIM_MR2_INT :Interrupt for Match channel 2
|
||||
* - TIM_MR3_INT :Interrupt for Match channel 3
|
||||
* - TIM_CR0_INT :Interrupt for Capture channel 0
|
||||
* - TIM_CR1_INT :Interrupt for Capture channel 1
|
||||
* @return FlagStatus
|
||||
* - SET :interrupt
|
||||
* - RESET :no interrupt
|
||||
**********************************************************************/
|
||||
FlagStatus TIM_GetIntStatus(LPC_TIMERn_Type *TIMx, TIM_INT_TYPE IntFlag)
|
||||
{
|
||||
uint8_t temp;
|
||||
CHECK_PARAM(PARAM_TIMx(TIMx));
|
||||
CHECK_PARAM(PARAM_TIM_INT_TYPE(IntFlag));
|
||||
temp = (TIMx->IR)& TIM_IR_CLR(IntFlag);
|
||||
if (temp)
|
||||
return SET;
|
||||
|
||||
return RESET;
|
||||
|
||||
}
|
||||
/*********************************************************************//**
|
||||
* @brief Get Capture Interrupt Status
|
||||
* @param[in] TIMx Timer selection, should be:
|
||||
* - LPC_TIM0 :TIMER0 peripheral
|
||||
* - LPC_TIM1 :TIMER1 peripheral
|
||||
* - LPC_TIM2 :TIMER2 peripheral
|
||||
* - LPC_TIM3 :TIMER3 peripheral
|
||||
* @param[in] IntFlag: interrupt type, should be:
|
||||
* - TIM_MR0_INT :Interrupt for Match channel 0
|
||||
* - TIM_MR1_INT :Interrupt for Match channel 1
|
||||
* - TIM_MR2_INT :Interrupt for Match channel 2
|
||||
* - TIM_MR3_INT :Interrupt for Match channel 3
|
||||
* - TIM_CR0_INT :Interrupt for Capture channel 0
|
||||
* - TIM_CR1_INT :Interrupt for Capture channel 1
|
||||
* @return FlagStatus
|
||||
* - SET :interrupt
|
||||
* - RESET :no interrupt
|
||||
**********************************************************************/
|
||||
FlagStatus TIM_GetIntCaptureStatus(LPC_TIMERn_Type *TIMx, TIM_INT_TYPE IntFlag)
|
||||
{
|
||||
uint8_t temp;
|
||||
CHECK_PARAM(PARAM_TIMx(TIMx));
|
||||
CHECK_PARAM(PARAM_TIM_INT_TYPE(IntFlag));
|
||||
temp = (TIMx->IR) & (1<<(4+IntFlag));
|
||||
if(temp)
|
||||
return SET;
|
||||
return RESET;
|
||||
}
|
||||
/*********************************************************************//**
|
||||
* @brief Clear Interrupt pending
|
||||
* @param[in] TIMx Timer selection, should be:
|
||||
* - LPC_TIM0 :TIMER0 peripheral
|
||||
* - LPC_TIM1 :TIMER1 peripheral
|
||||
* - LPC_TIM2 :TIMER2 peripheral
|
||||
* - LPC_TIM3 :TIMER3 peripheral
|
||||
* @param[in] IntFlag: interrupt type, should be:
|
||||
* - TIM_MR0_INT :Interrupt for Match channel 0
|
||||
* - TIM_MR1_INT :Interrupt for Match channel 1
|
||||
* - TIM_MR2_INT :Interrupt for Match channel 2
|
||||
* - TIM_MR3_INT :Interrupt for Match channel 3
|
||||
* - TIM_CR0_INT :Interrupt for Capture channel 0
|
||||
* - TIM_CR1_INT :Interrupt for Capture channel 1
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void TIM_ClearIntPending(LPC_TIMERn_Type *TIMx, TIM_INT_TYPE IntFlag)
|
||||
{
|
||||
CHECK_PARAM(PARAM_TIMx(TIMx));
|
||||
CHECK_PARAM(PARAM_TIM_INT_TYPE(IntFlag));
|
||||
TIMx->IR = TIM_IR_CLR(IntFlag);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Clear Capture Interrupt pending
|
||||
* @param[in] TIMx Timer selection, should be
|
||||
* - LPC_TIM0 :TIMER0 peripheral
|
||||
* - LPC_TIM1 :TIMER1 peripheral
|
||||
* - LPC_TIM2 :TIMER2 peripheral
|
||||
* - LPC_TIM3 :TIMER3 peripheral
|
||||
* @param[in] IntFlag interrupt type, should be:
|
||||
* - TIM_MR0_INT :Interrupt for Match channel 0
|
||||
* - TIM_MR1_INT :Interrupt for Match channel 1
|
||||
* - TIM_MR2_INT :Interrupt for Match channel 2
|
||||
* - TIM_MR3_INT :Interrupt for Match channel 3
|
||||
* - TIM_CR0_INT :Interrupt for Capture channel 0
|
||||
* - TIM_CR1_INT :Interrupt for Capture channel 1
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void TIM_ClearIntCapturePending(LPC_TIMERn_Type *TIMx, TIM_INT_TYPE IntFlag)
|
||||
{
|
||||
CHECK_PARAM(PARAM_TIMx(TIMx));
|
||||
CHECK_PARAM(PARAM_TIM_INT_TYPE(IntFlag));
|
||||
TIMx->IR = (1<<(4+IntFlag));
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Configuration for Timer at initial time
|
||||
* @param[in] TimerCounterMode timer counter mode, should be:
|
||||
* - TIM_TIMER_MODE :Timer mode
|
||||
* - TIM_COUNTER_RISING_MODE :Counter rising mode
|
||||
* - TIM_COUNTER_FALLING_MODE :Counter falling mode
|
||||
* - TIM_COUNTER_ANY_MODE :Counter on both edges
|
||||
* @param[in] TIM_ConfigStruct pointer to TIM_TIMERCFG_Type or
|
||||
* TIM_COUNTERCFG_Type
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void TIM_ConfigStructInit(TIM_MODE_OPT TimerCounterMode, void *TIM_ConfigStruct)
|
||||
{
|
||||
if (TimerCounterMode == TIM_TIMER_MODE )
|
||||
{
|
||||
TIM_TIMERCFG_Type * pTimeCfg = (TIM_TIMERCFG_Type *)TIM_ConfigStruct;
|
||||
pTimeCfg->PrescaleOption = TIM_PRESCALE_USVAL;
|
||||
pTimeCfg->PrescaleValue = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
TIM_COUNTERCFG_Type * pCounterCfg = (TIM_COUNTERCFG_Type *)TIM_ConfigStruct;
|
||||
pCounterCfg->CountInputSelect = TIM_COUNTER_INCAP0;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Initial Timer/Counter device
|
||||
* Set Clock frequency for Timer
|
||||
* Set initial configuration for Timer
|
||||
* @param[in] TIMx Timer selection, should be:
|
||||
* - LPC_TIM0 :TIMER0 peripheral
|
||||
* - LPC_TIM1 :TIMER1 peripheral
|
||||
* - LPC_TIM2 :TIMER2 peripheral
|
||||
* - LPC_TIM3 :TIMER3 peripheral
|
||||
* @param[in] TimerCounterMode Timer counter mode, should be:
|
||||
* - TIM_TIMER_MODE :Timer mode
|
||||
* - TIM_COUNTER_RISING_MODE :Counter rising mode
|
||||
* - TIM_COUNTER_FALLING_MODE :Counter falling mode
|
||||
* - TIM_COUNTER_ANY_MODE :Counter on both edges
|
||||
* @param[in] TIM_ConfigStruct pointer to TIM_TIMERCFG_Type
|
||||
* that contains the configuration information for the
|
||||
* specified Timer peripheral.
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void TIM_Init(LPC_TIMERn_Type *TIMx, TIM_MODE_OPT TimerCounterMode, void *TIM_ConfigStruct)
|
||||
{
|
||||
TIM_TIMERCFG_Type *pTimeCfg;
|
||||
TIM_COUNTERCFG_Type *pCounterCfg;
|
||||
|
||||
CHECK_PARAM(PARAM_TIMx(TIMx));
|
||||
CHECK_PARAM(PARAM_TIM_MODE_OPT(TimerCounterMode));
|
||||
|
||||
//set power
|
||||
if (TIMx== LPC_TIMER0)
|
||||
{
|
||||
|
||||
}
|
||||
else if (TIMx== LPC_TIMER1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
else if (TIMx== LPC_TIMER2)
|
||||
{
|
||||
|
||||
}
|
||||
else if (TIMx== LPC_TIMER3)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TIMx->CCR &= ~TIM_CTCR_MODE_MASK;
|
||||
TIMx->CCR |= TIM_TIMER_MODE;
|
||||
|
||||
TIMx->TC =0;
|
||||
TIMx->PC =0;
|
||||
TIMx->PR =0;
|
||||
TIMx->TCR |= (1<<1); //Reset Counter
|
||||
TIMx->TCR &= ~(1<<1); //release reset
|
||||
if (TimerCounterMode == TIM_TIMER_MODE )
|
||||
{
|
||||
pTimeCfg = (TIM_TIMERCFG_Type *)TIM_ConfigStruct;
|
||||
if (pTimeCfg->PrescaleOption == TIM_PRESCALE_TICKVAL)
|
||||
{
|
||||
TIMx->PR = pTimeCfg->PrescaleValue -1 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
TIMx->PR = converUSecToVal (converPtrToTimeNum(TIMx),pTimeCfg->PrescaleValue)-1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
pCounterCfg = (TIM_COUNTERCFG_Type *)TIM_ConfigStruct;
|
||||
TIMx->CCR &= ~TIM_CTCR_INPUT_MASK;
|
||||
if (pCounterCfg->CountInputSelect == TIM_COUNTER_INCAP1)
|
||||
TIMx->CCR |= _BIT(2);
|
||||
}
|
||||
|
||||
// Clear interrupt pending
|
||||
TIMx->IR = 0xFFFFFFFF;
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Close Timer/Counter device
|
||||
* @param[in] TIMx Pointer to timer device, should be:
|
||||
* - LPC_TIM0 :TIMER0 peripheral
|
||||
* - LPC_TIM1 :TIMER1 peripheral
|
||||
* - LPC_TIM2 :TIMER2 peripheral
|
||||
* - LPC_TIM3 :TIMER3 peripheral
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void TIM_DeInit (LPC_TIMERn_Type *TIMx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_TIMx(TIMx));
|
||||
// Disable timer/counter
|
||||
TIMx->TCR = 0x00;
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Start/Stop Timer/Counter device
|
||||
* @param[in] TIMx Pointer to timer device, should be:
|
||||
* - LPC_TIM0 :TIMER0 peripheral
|
||||
* - LPC_TIM1 :TIMER1 peripheral
|
||||
* - LPC_TIM2 :TIMER2 peripheral
|
||||
* - LPC_TIM3 :TIMER3 peripheral
|
||||
* @param[in] NewState
|
||||
* - ENABLE :Set timer enable
|
||||
* - DISABLE :Disable timer
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void TIM_Cmd(LPC_TIMERn_Type *TIMx, FunctionalState NewState)
|
||||
{
|
||||
CHECK_PARAM(PARAM_TIMx(TIMx));
|
||||
if (NewState == ENABLE)
|
||||
{
|
||||
TIMx->TCR |= TIM_ENABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
TIMx->TCR &= ~TIM_ENABLE;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Reset Timer/Counter device,
|
||||
* Make TC and PC are synchronously reset on the next
|
||||
* positive edge of PCLK
|
||||
* @param[in] TIMx Pointer to timer device, should be:
|
||||
* - LPC_TIM0 :TIMER0 peripheral
|
||||
* - LPC_TIM1 :TIMER1 peripheral
|
||||
* - LPC_TIM2 :TIMER2 peripheral
|
||||
* - LPC_TIM3 :TIMER3 peripheral
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void TIM_ResetCounter(LPC_TIMERn_Type *TIMx)
|
||||
{
|
||||
CHECK_PARAM(PARAM_TIMx(TIMx));
|
||||
TIMx->TCR |= TIM_RESET;
|
||||
TIMx->TCR &= ~TIM_RESET;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Configuration for Match register
|
||||
* @param[in] TIMx Pointer to timer device, should be:
|
||||
* - LPC_TIM0 :TIMER0 peripheral
|
||||
* - LPC_TIM1 :TIMER1 peripheral
|
||||
* - LPC_TIM2 :TIMER2 peripheral
|
||||
* - LPC_TIM3 :TIMER3 peripheral
|
||||
* @param[in] TIM_MatchConfigStruct Pointer to TIM_MATCHCFG_Type
|
||||
* - MatchChannel : choose channel 0 or 1
|
||||
* - IntOnMatch : if SET, interrupt will be generated when MRxx match
|
||||
* the value in TC
|
||||
* - StopOnMatch : if SET, TC and PC will be stopped whenM Rxx match
|
||||
* the value in TC
|
||||
* - ResetOnMatch : if SET, Reset on MR0 when MRxx match
|
||||
* the value in TC
|
||||
* -ExtMatchOutputType: Select output for external match
|
||||
* + 0: Do nothing for external output pin if match
|
||||
* + 1: Force external output pin to low if match
|
||||
* + 2: Force external output pin to high if match
|
||||
* + 3: Toggle external output pin if match
|
||||
* MatchValue: Set the value to be compared with TC value
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void TIM_ConfigMatch(LPC_TIMERn_Type *TIMx, TIM_MATCHCFG_Type *TIM_MatchConfigStruct)
|
||||
{
|
||||
|
||||
CHECK_PARAM(PARAM_TIMx(TIMx));
|
||||
CHECK_PARAM(PARAM_TIM_EXTMATCH_OPT(TIM_MatchConfigStruct->ExtMatchOutputType));
|
||||
|
||||
switch(TIM_MatchConfigStruct->MatchChannel)
|
||||
{
|
||||
case 0:
|
||||
TIMx->MR[0] = TIM_MatchConfigStruct->MatchValue;
|
||||
break;
|
||||
case 1:
|
||||
TIMx->MR[1] = TIM_MatchConfigStruct->MatchValue;
|
||||
break;
|
||||
case 2:
|
||||
TIMx->MR[2] = TIM_MatchConfigStruct->MatchValue;
|
||||
break;
|
||||
case 3:
|
||||
TIMx->MR[3] = TIM_MatchConfigStruct->MatchValue;
|
||||
break;
|
||||
default:
|
||||
//Error match value
|
||||
//Error loop
|
||||
while(1);
|
||||
}
|
||||
//interrupt on MRn
|
||||
TIMx->MCR &=~TIM_MCR_CHANNEL_MASKBIT(TIM_MatchConfigStruct->MatchChannel);
|
||||
|
||||
if (TIM_MatchConfigStruct->IntOnMatch)
|
||||
TIMx->MCR |= TIM_INT_ON_MATCH(TIM_MatchConfigStruct->MatchChannel);
|
||||
|
||||
//reset on MRn
|
||||
if (TIM_MatchConfigStruct->ResetOnMatch)
|
||||
TIMx->MCR |= TIM_RESET_ON_MATCH(TIM_MatchConfigStruct->MatchChannel);
|
||||
|
||||
//stop on MRn
|
||||
if (TIM_MatchConfigStruct->StopOnMatch)
|
||||
TIMx->MCR |= TIM_STOP_ON_MATCH(TIM_MatchConfigStruct->MatchChannel);
|
||||
|
||||
// match output type
|
||||
|
||||
TIMx->EMR &= ~TIM_EM_MASK(TIM_MatchConfigStruct->MatchChannel);
|
||||
TIMx->EMR |= TIM_EM_SET(TIM_MatchConfigStruct->MatchChannel,TIM_MatchConfigStruct->ExtMatchOutputType);
|
||||
}
|
||||
/*********************************************************************//**
|
||||
* @brief Update Match value
|
||||
* @param[in] TIMx Pointer to timer device, should be:
|
||||
* - LPC_TIM0 :TIMER0 peripheral
|
||||
* - LPC_TIM1 :TIMER1 peripheral
|
||||
* - LPC_TIM2 :TIMER2 peripheral
|
||||
* - LPC_TIM3 :TIMER3 peripheral
|
||||
* @param[in] MatchChannel Match channel, should be: 0..3
|
||||
* @param[in] MatchValue updated match value
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void TIM_UpdateMatchValue(LPC_TIMERn_Type *TIMx,uint8_t MatchChannel, uint32_t MatchValue)
|
||||
{
|
||||
CHECK_PARAM(PARAM_TIMx(TIMx));
|
||||
switch(MatchChannel)
|
||||
{
|
||||
case 0:
|
||||
TIMx->MR[0] = MatchValue;
|
||||
break;
|
||||
case 1:
|
||||
TIMx->MR[1] = MatchValue;
|
||||
break;
|
||||
case 2:
|
||||
TIMx->MR[2] = MatchValue;
|
||||
break;
|
||||
case 3:
|
||||
TIMx->MR[3] = MatchValue;
|
||||
break;
|
||||
default:
|
||||
//Error Loop
|
||||
while(1);
|
||||
}
|
||||
|
||||
}
|
||||
/*********************************************************************//**
|
||||
* @brief Configuration for Capture register
|
||||
* @param[in] TIMx Pointer to timer device, should be:
|
||||
* - LPC_TIM0 :TIMER0 peripheral
|
||||
* - LPC_TIM1 :TIMER1 peripheral
|
||||
* - LPC_TIM2 :TIMER2 peripheral
|
||||
* - LPC_TIM3 :TIMER3 peripheral
|
||||
* @param[in] TIM_CaptureConfigStruct Pointer to TIM_CAPTURECFG_Type
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void TIM_ConfigCapture(LPC_TIMERn_Type *TIMx, TIM_CAPTURECFG_Type *TIM_CaptureConfigStruct)
|
||||
{
|
||||
|
||||
CHECK_PARAM(PARAM_TIMx(TIMx));
|
||||
TIMx->CCR &= ~TIM_CCR_CHANNEL_MASKBIT(TIM_CaptureConfigStruct->CaptureChannel);
|
||||
|
||||
if (TIM_CaptureConfigStruct->RisingEdge)
|
||||
TIMx->CCR |= TIM_CAP_RISING(TIM_CaptureConfigStruct->CaptureChannel);
|
||||
|
||||
if (TIM_CaptureConfigStruct->FallingEdge)
|
||||
TIMx->CCR |= TIM_CAP_FALLING(TIM_CaptureConfigStruct->CaptureChannel);
|
||||
|
||||
if (TIM_CaptureConfigStruct->IntOnCaption)
|
||||
TIMx->CCR |= TIM_INT_ON_CAP(TIM_CaptureConfigStruct->CaptureChannel);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Read value of capture register in timer/counter device
|
||||
* @param[in] TIMx Pointer to timer/counter device, should be:
|
||||
* - LPC_TIM0 :TIMER0 peripheral
|
||||
* - LPC_TIM1 :TIMER1 peripheral
|
||||
* - LPC_TIM2 :TIMER2 peripheral
|
||||
* - LPC_TIM3 :TIMER3 peripheral
|
||||
* @param[in] CaptureChannel: capture channel number, should be:
|
||||
* - TIM_COUNTER_INCAP0: CAPn.0 input pin for TIMERn
|
||||
* - TIM_COUNTER_INCAP1: CAPn.1 input pin for TIMERn
|
||||
* - TIM_COUNTER_INCAP1: CAPn.2 input pin for TIMERn
|
||||
* - TIM_COUNTER_INCAP1: CAPn.3 input pin for TIMERn
|
||||
* @return Value of capture register
|
||||
**********************************************************************/
|
||||
uint32_t TIM_GetCaptureValue(LPC_TIMERn_Type *TIMx, TIM_COUNTER_INPUT_OPT CaptureChannel)
|
||||
{
|
||||
CHECK_PARAM(PARAM_TIMx(TIMx));
|
||||
CHECK_PARAM(PARAM_TIM_COUNTER_INPUT_OPT(CaptureChannel));
|
||||
|
||||
switch(CaptureChannel){
|
||||
case 0: return TIMx->CR[0];
|
||||
case 1: return TIMx->CR[1];
|
||||
case 2: return TIMx->CR[2];
|
||||
case 3: return TIMx->CR[3];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*---------------Advanced TIMER functions -----------------------------------------*/
|
||||
/*********************************************************************//**
|
||||
* @brief Timer wait (microseconds)
|
||||
* @param[in] time number of microseconds waiting
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void TIM_Waitus(uint32_t time)
|
||||
{
|
||||
TIM_MATCHCFG_Type MatchConfigStruct;
|
||||
LPC_TIMER0->IR = 0xFFFFFFFF;
|
||||
|
||||
MatchConfigStruct.MatchChannel = 0;
|
||||
MatchConfigStruct.IntOnMatch = ENABLE;
|
||||
MatchConfigStruct.ResetOnMatch = ENABLE;
|
||||
MatchConfigStruct.StopOnMatch = ENABLE;
|
||||
MatchConfigStruct.ExtMatchOutputType = 0;
|
||||
MatchConfigStruct.MatchValue = time;
|
||||
|
||||
TIM_ConfigMatch(LPC_TIMER0, &MatchConfigStruct);
|
||||
TIM_Cmd(LPC_TIMER0,ENABLE);
|
||||
//wait until interrupt flag occur
|
||||
while(!(LPC_TIMER0->IR & 0x01));
|
||||
TIM_ResetCounter(LPC_TIMER0);
|
||||
}
|
||||
/*********************************************************************//**
|
||||
* @brief Timer wait (milliseconds)
|
||||
* @param[in] time number of millisecond waiting
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void TIM_Waitms(uint32_t time)
|
||||
{
|
||||
TIM_Waitus(time * 1000);
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _TIMER */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,273 @@
|
||||
/**********************************************************************
|
||||
* $Id$ lpc43xx_wwdt.c 2011-06-02
|
||||
*//**
|
||||
* @file lpc43xx_wwdt.c
|
||||
* @brief Contains all functions support for WDT firmware library
|
||||
* on lpc43xx
|
||||
* @version 1.0
|
||||
* @date 02. June. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors’
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
/* Peripheral group ----------------------------------------------------------- */
|
||||
/** @addtogroup WWDT
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------- */
|
||||
#include "lpc43xx_wwdt.h"
|
||||
|
||||
/* If this source file built with example, the lpc43xx FW library configuration
|
||||
* file in each example directory ("lpc43xx_libcfg.h") must be included,
|
||||
* otherwise the default FW library configuration file must be included instead
|
||||
*/
|
||||
#ifdef __BUILD_WITH_EXAMPLE__
|
||||
#include "lpc43xx_libcfg.h"
|
||||
#else
|
||||
#include "lpc43xx_libcfg_default.h"
|
||||
#endif /* __BUILD_WITH_EXAMPLE__ */
|
||||
|
||||
|
||||
#ifdef _WWDT
|
||||
|
||||
void WWDT_SetTimeOut(uint32_t timeout);
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Update WDT timeout value and feed
|
||||
* @param[in] timeout WDT timeout (us)
|
||||
* @return none
|
||||
**********************************************************************/
|
||||
void WWDT_SetTimeOut(uint32_t timeout)
|
||||
{
|
||||
uint32_t timeoutVal;
|
||||
|
||||
timeoutVal = WDT_GET_FROM_USEC(timeout);
|
||||
|
||||
if(timeoutVal < WWDT_TIMEOUT_MIN)
|
||||
{
|
||||
timeoutVal = WWDT_TIMEOUT_MIN;
|
||||
}
|
||||
else if (timeoutVal > WWDT_TIMEOUT_MAX)
|
||||
{
|
||||
timeoutVal = WWDT_TIMEOUT_MAX;
|
||||
}
|
||||
|
||||
LPC_WWDT->TC = timeoutVal;
|
||||
}
|
||||
/* Public Functions ----------------------------------------------------------- */
|
||||
/** @addtogroup WDT_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Initial for Watchdog function
|
||||
* @param[in] none
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void WWDT_Init(void)
|
||||
{
|
||||
LPC_WWDT->MOD = 0; // Clear time out and interrupt flags
|
||||
LPC_WWDT->TC = WWDT_TIMEOUT_MIN; // Reset time out
|
||||
LPC_WWDT->WARNINT= 0; // Reset warning value
|
||||
LPC_WWDT->WINDOW = WWDT_WINDOW_MAX; // Reset window value
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Update WDT timeout value and feed
|
||||
* @param[in] TimeOut TimeOut value to be updated, should be in range:
|
||||
* 2048 .. 134217728
|
||||
* @return None
|
||||
*********************************************************************/
|
||||
void WDT_UpdateTimeOut(uint32_t TimeOut)
|
||||
{
|
||||
/* check WDPROTECT,
|
||||
* if it is enable, wait until the counter is below the value of
|
||||
* WDWARNINT and WDWINDOW
|
||||
*/
|
||||
if(LPC_WWDT->MOD & (1<<4))
|
||||
{
|
||||
while((LPC_WWDT->TV <(LPC_WWDT->WARNINT & WWDT_WDWARNINT_MASK))\
|
||||
&&(LPC_WWDT->TV <(LPC_WWDT->WINDOW & WWDT_WDTC_MASK)));
|
||||
}
|
||||
|
||||
WWDT_SetTimeOut(TimeOut);
|
||||
}
|
||||
/********************************************************************//**
|
||||
* @brief After set WDTEN, call this function to start Watchdog
|
||||
* or reload the Watchdog timer
|
||||
* @param[in] None
|
||||
* @return None
|
||||
*********************************************************************/
|
||||
void WWDT_Feed (void)
|
||||
{
|
||||
LPC_WWDT->FEED = 0xAA;
|
||||
|
||||
LPC_WWDT->FEED = 0x55;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Update WDT timeout value and feed
|
||||
* @param[in] WarnTime time to generate watchdog warning interrupt(us)
|
||||
* should be in range: 2048 .. 8192
|
||||
* @return None
|
||||
*********************************************************************/
|
||||
void WWDT_SetWarning(uint32_t WarnTime)
|
||||
{
|
||||
uint32_t warnVal;
|
||||
|
||||
warnVal = WDT_GET_FROM_USEC(WarnTime);
|
||||
|
||||
if(warnVal <= WWDT_WARNINT_MIN)
|
||||
{
|
||||
warnVal = WWDT_WARNINT_MIN;
|
||||
}
|
||||
else if (warnVal >= WWDT_WARNINT_MAX)
|
||||
{
|
||||
warnVal = WWDT_WARNINT_MAX;
|
||||
}
|
||||
|
||||
LPC_WWDT->WARNINT = warnVal;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Update WDT timeout value and feed
|
||||
* @param[in] WindowedTime expected time to set watchdog window event(us)
|
||||
* @return none
|
||||
*********************************************************************/
|
||||
void WWDT_SetWindow(uint32_t WindowedTime)
|
||||
{
|
||||
uint32_t wndVal;
|
||||
|
||||
wndVal = WDT_GET_FROM_USEC(WindowedTime);
|
||||
|
||||
if(wndVal <= WWDT_WINDOW_MIN)
|
||||
{
|
||||
wndVal = WWDT_WINDOW_MIN;
|
||||
}
|
||||
else if (wndVal >= WWDT_WINDOW_MAX)
|
||||
{
|
||||
wndVal = WWDT_WINDOW_MAX;
|
||||
}
|
||||
|
||||
LPC_WWDT->WINDOW = wndVal;
|
||||
}
|
||||
/*********************************************************************//**
|
||||
* @brief Enable/Disable WWDT activity
|
||||
* @param[in] None
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void WWDT_Configure(st_Wdt_Config wdtCfg)
|
||||
{
|
||||
WWDT_SetTimeOut(wdtCfg.wdtTmrConst);
|
||||
|
||||
if(wdtCfg.wdtReset)
|
||||
{
|
||||
LPC_WWDT->MOD |= WWDT_WDMOD_WDRESET;
|
||||
}
|
||||
else
|
||||
{
|
||||
LPC_WWDT->MOD &= ~WWDT_WDMOD_WDRESET;
|
||||
}
|
||||
|
||||
if(wdtCfg.wdtProtect)
|
||||
{
|
||||
LPC_WWDT->MOD |= WWDT_WDMOD_WDPROTECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
LPC_WWDT->MOD &= ~WWDT_WDMOD_WDPROTECT;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
* @brief Enable WWDT activity
|
||||
* @param[in] None
|
||||
* @return None
|
||||
**********************************************************************/
|
||||
void WWDT_Start(void)
|
||||
{
|
||||
LPC_WWDT->MOD |= WWDT_WDMOD_WDEN;
|
||||
WWDT_Feed();
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Read WWDT status flag
|
||||
* @param[in] Status kind of status flag that you want to get, should be:
|
||||
* - WWDT_WARNINT_FLAG: watchdog interrupt flag
|
||||
* - WWDT_TIMEOUT_FLAG: watchdog time-out flag
|
||||
* @return Time out flag status of WDT
|
||||
*********************************************************************/
|
||||
FlagStatus WWDT_GetStatus (uint8_t Status)
|
||||
{
|
||||
if(Status == WWDT_WARNINT_FLAG)
|
||||
{
|
||||
return ((FlagStatus)(LPC_WWDT->MOD & (1<<3)));
|
||||
}
|
||||
else if (Status == WWDT_TIMEOUT_FLAG)
|
||||
{
|
||||
return ((FlagStatus)(LPC_WWDT->MOD & (1<<2)));
|
||||
}
|
||||
return (FlagStatus)RESET;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Read WWDT status flag
|
||||
* @param[in] Status kind of status flag that you want to get, should be:
|
||||
* - WWDT_WARNINT_FLAG: watchdog interrupt flag
|
||||
* - WWDT_TIMEOUT_FLAG: watchdog time-out flag
|
||||
* @return Time out flag status of WDT
|
||||
*********************************************************************/
|
||||
void WWDT_ClearStatusFlag (uint8_t flag)
|
||||
{
|
||||
if(flag == WWDT_WARNINT_FLAG)
|
||||
{
|
||||
// Write 1 to this bit to clear itself
|
||||
LPC_WWDT->MOD |= WWDT_WDMOD_WDINT;
|
||||
}
|
||||
else if(flag == WWDT_TIMEOUT_FLAG)
|
||||
{
|
||||
// Write 0 to this bit to clear itself
|
||||
LPC_WWDT->MOD &= ~ WWDT_WDMOD_WDTOF;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
* @brief Get the current value of WDT
|
||||
* @param[in] None
|
||||
* @return current value of WDT
|
||||
*********************************************************************/
|
||||
uint32_t WWDT_GetCurrentCount(void)
|
||||
{
|
||||
return LPC_WWDT->TV;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* _WWDT */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,141 @@
|
||||
/**********************************************************************
|
||||
* $Id$ system_lpc43xx.c 2012-05-21
|
||||
*//**
|
||||
* @file system_lpc43xx.c
|
||||
* @brief Cortex-M3 Device System Source File for NXP lpc43xx Series.
|
||||
* @version 1.0
|
||||
* @date 21. May. 2011
|
||||
* @author NXP MCU SW Application Team
|
||||
*
|
||||
* Copyright(C) 2011, NXP Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
***********************************************************************
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* products. This software is supplied "AS IS" without any warranties.
|
||||
* NXP Semiconductors assumes no responsibility or liability for the
|
||||
* use of the software, conveys no license or title under any patent,
|
||||
* copyright, or mask work right to the product. NXP Semiconductors
|
||||
* reserves the right to make changes in the software without
|
||||
* notification. NXP Semiconductors also make no representation or
|
||||
* warranty that such application will be suitable for the specified
|
||||
* use without further testing or modification.
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors'
|
||||
* relevant copyright in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
**********************************************************************/
|
||||
|
||||
#include "LPC43xx.h"
|
||||
#if !defined(__CODE_RED)
|
||||
#include "fpu_enable.h"
|
||||
#endif
|
||||
|
||||
// CodeRed - call clock init code by default
|
||||
#ifdef __CODE_RED
|
||||
#include "lpc43xx_cgu.h"
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define __IRC (12000000UL) /* IRC Oscillator frequency */
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Clock Variable definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = __IRC; /*!< System Clock Frequency (Core Clock)*/
|
||||
|
||||
extern uint32_t getPC(void);
|
||||
|
||||
/**
|
||||
* Initialize the system
|
||||
*
|
||||
* @param none
|
||||
* @return none
|
||||
*
|
||||
* @brief Setup the microcontroller system.
|
||||
* Initialize the System.
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
uint32_t org;
|
||||
|
||||
#if !defined(__CODE_RED)
|
||||
#if defined(CORE_M4) && defined(USE_FPU)
|
||||
fpuEnable();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(CORE_M0)
|
||||
// Set up Cortex_M3 or M4 VTOR register to point to vector table
|
||||
// This code uses a toolchain defined symbol to locate the vector table
|
||||
// If this is not completed, interrupts are likely to cause an exception.
|
||||
unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08;
|
||||
#if defined(__IAR_SYSTEMS_ICC__)
|
||||
extern void *__vector_table;
|
||||
|
||||
org = *pSCB_VTOR = (unsigned int)&__vector_table;
|
||||
#elif defined(__CODE_RED)
|
||||
extern void *g_pfnVectors;
|
||||
|
||||
// CodeRed - correct to assign address of variable not contents
|
||||
// org = *pSCB_VTOR = (unsigned int)g_pfnVectors;
|
||||
org = *pSCB_VTOR = (unsigned int)&g_pfnVectors;
|
||||
#elif defined(__ARMCC_VERSION)
|
||||
extern void *__Vectors;
|
||||
|
||||
org = *pSCB_VTOR = (unsigned int)&__Vectors;
|
||||
#else
|
||||
#error Unknown compiler
|
||||
#endif
|
||||
#else
|
||||
// Cortex M0?
|
||||
#error Cannot configure VTOR on Cortex_M0
|
||||
#endif
|
||||
|
||||
// LPC18xx/LPC43xx ROM sets the PLL to run from IRC and drive the part
|
||||
// at 96 MHz out of reset
|
||||
SystemCoreClock = 96000000;
|
||||
|
||||
// In case we are running from external flash, (booted by boot rom)
|
||||
// We enable the EMC buffer to improve performance.
|
||||
if(org == 0x1C000000)
|
||||
{
|
||||
/*Enable Buffer for External Flash*/
|
||||
LPC_EMC->STATICCONFIG0 |= 1<<19;
|
||||
}
|
||||
|
||||
// CodeRed - call clock init code by default
|
||||
#ifdef __CODE_RED
|
||||
// Call clock initialisation code
|
||||
CGU_Init();
|
||||
#endif
|
||||
|
||||
// In case we are running from internal flash, we configure the flash
|
||||
// accelerator. This is a conservative value that should work up to 204
|
||||
// MHz on the LPC43xx or 180 MHz on the LPC18xx. This value may change
|
||||
// as the chips are characterized and should also change based on
|
||||
// core clock speed.
|
||||
#define FLASH_ACCELERATOR_SPEED 6
|
||||
#ifdef INTERNAL_FLASH
|
||||
{
|
||||
uint32_t *MAM,t;
|
||||
|
||||
// Set up flash controller for both banks
|
||||
// Bank A
|
||||
MAM = (uint32_t *)(LPC_CREG_BASE + 0x120);
|
||||
t=*MAM;
|
||||
t &= ~(0xF<<12);
|
||||
*MAM = t | (FLASH_ACCELERATOR_SPEED<<12);
|
||||
// Bank B
|
||||
MAM = (uint32_t *)(LPC_CREG_BASE + 0x124);
|
||||
t=*MAM;
|
||||
t &= ~(0xF<<12);
|
||||
*MAM = t | (FLASH_ACCELERATOR_SPEED<<12);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user