move mcu cmsis file to /mcu

This commit is contained in:
hathach
2014-03-12 17:20:24 +07:00
parent d98bc0a64b
commit 8db8294af2
190 changed files with 0 additions and 0 deletions
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
}