18.7.2 Timer Control Register (TMR16B0TCR and TMR16B1TCR)
The Timer Control Register (TCR) is used to control the operation of the counter/timer.
The 16-bit Timer Counter is incremented when the Prescale Counter reaches its terminal count. Unless it is reset before reaching its upper limit, the TC will count up through the
value 0x0000 FFFF and then wrap back to the value 0x0000 0000. This event does not cause an interrupt, but a Match register can be used to detect an overflow if needed.
Table 282. Timer Control Register (TMR16B0TCR - address 0x4000 C004 and TMR16B1TCR - address 0x4001 0004)
0 CEn Counter Enable. When one, the Timer Counter and Prescale Counter are enabled for counting. When zero,
the counters are disabled. 0
1 CRst Counter Reset. When one, the Timer Counter and the Prescale Counter are synchronously reset on the next
positive edge of PCLK. The counters remain reset until TCR[1] is returned to zero. 0
31:2 - Reserved, user software should not write ones to reserved bits. The value read from a reserved bit is not
18.7.3 Timer Counter (TMR16B0TC - address 0x4000 C008 and TMR16B1TC - address 0x4001 0008)
The 16-bit Timer Counter is incremented when the Prescale Counter reaches its terminal
count. Unless it is reset before reaching its upper limit, the TC will count up through the
value 0x0000 FFFF and then wrap back to the value 0x0000 0000. This event does not
cause an interrupt, but a Match register can be used to detect an overflow if needed.
Table 283: Timer counter registers (TMR16B0TC, address 0x4000 C008 and TMR16B1TC
0x4001 0008)
15:0 TC Timer counter value. 0
31:16 - Reserved
18.7.4 Prescale Register (TMR16B0PR - address 0x4000 C00C and TMR16B1PR - address 0x4001 000C)
The 16-bit Prescale Register specifies the maximum value for the Prescale Counter.
Table 284: Prescale registers (TMR16B0PR, address 0x4000 C00C and TMR16B1PR
0x4001 000C)
15:0 PR Prescale max value.
18.7.5 Prescale Counter register (TMR16B0PC - address 0x4000 C010 and TMR16B1PC - address 0x4001 0010)
The 16-bit Prescale Counter controls division of PCLK by some constant value before it is
applied to the Timer Counter. This allows control of the relationship between the resolution
of the timer and the maximum time before the timer overflows. The Prescale Counter is
incremented on every PCLK. When it reaches the value stored in the Prescale Register,
the Timer Counter is incremented, and the Prescale Counter is reset on the next PCLK.
This causes the TC to increment on every PCLK when PR = 0, every 2 PCLKs when
PR = 1, etc.
Table 285: Prescale counter registers (TMR16B0PC, address 0x4001 C010 and TMR16B1PC
0x4000 0010)
15:0 PC Prescale counter value. 0
31:16 - Reserved.
18.7.6 Match Control Register (TMR16B0MCR and TMR16B1MCR)
The Match Control Register is used to control what operations are performed when one of
the Match Registers matches the Timer Counter. The function of each of the bits is shown
in Table 286.
Table 286. Match Control Register (TMR16B0MCR - address 0x4000 C014 and TMR16B1MCR - address 0x4001 0014)
0 MR0I Interrupt on MR0: an interrupt is generated when MR0 matches the value in the TC. 0
1 Enabled
0 Disabled
1 MR0R Reset on MR0: the TC will be reset if MR0 matches it. 0
1 Enabled
0 Disabled
2 MR0S Stop on MR0: the TC and PC will be stopped and TCR[0] will be set to 0 if MR0 matches
the TC.
0
1 Enabled
0 Disabled
3 MR1I Interrupt on MR1: an interrupt is generated when MR1 matches the value in the TC. 0
1 Enabled
0 Disabled
4 MR1R Reset on MR1: the TC will be reset if MR1 matches it. 0
1 Enabled
0 Disabled
5 MR1S Stop on MR1: the TC and PC will be stopped and TCR[0] will be set to 0 if MR1 matches
the TC.
0
1 Enabled
0 Disabled
6 MR2I Interrupt on MR2: an interrupt is generated when MR2 matches the value in the TC. 0
1 Enabled
0 Disabled
7 MR2R Reset on MR2: the TC will be reset if MR2 matches it. 0
1 Enabled
0 Disabled
8 MR2S Stop on MR2: the TC and PC will be stopped and TCR[0] will be set to 0 if MR2 matches
the TC.
0
1 Enabled
0 Disabled
9 MR3I Interrupt on MR3: an interrupt is generated when MR3 matches the value in the TC. 0
1 Enabled
0 Disabled
10 MR3R Reset on MR3: the TC will be reset if MR3 matches it. 0
1 Enabled
0 Disabled
11 MR3S Stop on MR3: the TC and PC will be stopped and TCR[0] will be set to 0 if MR3 matches
the TC.
0
1 Enabled
0 Disabled
31:12 - Reserved, user software should not write ones to reserved bits. The value read from a
reserved bit is not defined.
18.7.7 Match Registers (TMR16B0MR0/1/2/3 - addresses 0x4000
C018/1C/20/24 and TMR16B1MR0/1/2/3 - addresses 0x4001 0018/1C/20/24)
The Match register values are continuously compared to the Timer Counter value. When
the two values are equal, actions can be triggered automatically. The action possibilities
are to generate an interrupt, reset the Timer Counter, or stop the timer. Actions are
controlled by the settings in the MCR register.
Table 287: Match registers (TMR16B0MR0 to 3, addresses 0x4000 C018 to 24 and
TMR16B1MR0 to 3, addresses 0x4001 0018 to 24)
15:0 MATCH Timer counter match value. 0
31:16 - Reserved.
18.7.8 Capture Control Register (TMR16B0CCR and TMR16B1CCR)
The Capture Control Register is used to control whether the Capture Register is loaded
with the value in the Counter/timer when the capture event occurs, and whether an
interrupt is generated by the capture event. Setting both the rising and falling bits at the
same time is a valid configuration, resulting in a capture event for both edges. In the
description below, n represents the Timer number, 0 or 1.
Table 288. Capture Control Register (TMR16B0CCR - address 0x4000 C028 and TMR16B1CCR - address
0x4001 0028)
0 CAP0RE Capture on CT16Bn_CAP0 rising edge: a sequence of 0 then 1 on CT16Bn_CAP0 will
cause CR0 to be loaded with the contents of TC. 0
1 Enabled
0 Disabled
1 CAP0FE Capture on CT16Bn_CAP0 falling edge: a sequence of 1 then 0 on CT16Bn_CAP0 will
cause CR0 to be loaded with the contents of TC. 0
1 Enabled
0 Disabled
2 CAP0I Interrupt on CT16Bn_CAP0 event: a CR0 load due to a CT16Bn_CAP0 event will
generate an interrupt. 0
1 Enabled
0 Disabled
31:3 - - Reserved, user software should not write ones to reserved bits. The value read from a
reserved bit is not defined.
18.7.9 Capture Register (CT16B0CR0 - address 0x4000 C02C and CT16B1CR0 - address 0x4001 002C)
Each Capture register is associated with a device pin and may be loaded with the
counter/timer value when a specified event occurs on that pin. The settings in the Capture
Control Register register determine whether the capture function is enabled, and whether
a capture event happens on the rising edge of the associated pin, the falling edge, or on
both edges.
Table 289: Capture registers (TMR16B0CR0, address 0x4000 C02C and TMR16B1CR0,
address 0x4001 002C)
15:0 CAP Timer counter capture value. 0
31:16 - Reserved.
18.7.10 External Match Register (TMR16B0EMR and TMR16B1EMR)
The External Match Register provides both control and status of the external match
channels and external match pins CT16B0_MAT[2:0] and CT16B1_MAT[1:0].
If the match outputs are configured as PWM output in the PWMCON registers
(Section 18.7.12), the function of the external match registers is determined by the PWM
rules (Section 18.7.13 “Rules for single edge controlled PWM outputs” on page 336).
18.7.11 Count Control Register (TMR16B0CTCR and TMR16B1CTCR)
The Count Control Register (CTCR) is used to select between Timer and Counter mode,
and in Counter mode to select the pin and edges for counting.
When Counter Mode is chosen as a mode of operation, the CAP input (selected by the
CTCR bits 3:2) is sampled on every rising edge of the PCLK clock. After comparing two
consecutive samples of this CAP input, one of the following four events is recognized:
rising edge, falling edge, either of edges or no changes in the level of the selected CAP
input. Only if the identified event occurs, and the event corresponds to the one selected by
bits 1:0 in the CTCR register, will the Timer Counter register be incremented.
Effective processing of the externally supplied clock to the counter has some limitations.
Since two successive rising edges of the PCLK clock are used to identify only one edge
on the CAP selected input, the frequency of the CAP input can not exceed one half of the
PCLK clock. Consequently, duration of the HIGH/LOW levels on the same CAP input in
this case can not be shorter than 1/(2 PCLK).
Table 292. Count Control Register (TMR16B0CTCR - address 0x4000 C070 and
TMR16B1CTCR - address 0x4001 0070)
1:0 CTM Counter/Timer Mode. This field selects which rising PCLK
edges can increment Timer’s Prescale Counter (PC), or clear
PC and increment Timer Counter (TC). 00
0x0 Timer Mode: every rising PCLK edge
0x1 Counter Mode: TC is incremented on rising edges on the
CAP input selected by bits 3:2.
0x2 Counter Mode: TC is incremented on falling edges on the
CAP input selected by bits 3:2.
0x3 Counter Mode: TC is incremented on both edges on the CAP
input selected by bits 3:2.
3:2 CIS Count Input Select. In counter mode (when bits 1:0 in this
register are not 00), these bits select which CAP pin is
sampled for clocking. Note: If Counter mode is selected in
the CTCR register, bits 2:0 in the Capture Control Register
(CCR) must be programmed as 000. 00
0x0 CT16Bn_CAP0
0x1 CT16Bn_CAP1
0x2 Reserved.
0x3 Reserved.
31:4 - - Reserved, user software should not write ones to reserved
bits. The value read from a reserved bit is not defined.
18.7.12 PWM Control register (TMR16B0PWMC and TMR16B1PWMC)
The PWM Control Register is used to configure the match outputs as PWM outputs. Each
match output can be independently set to perform either as PWM output or as match
output whose function is controlled by the External Match Register (EMR).
For timer 0, three single-edge controlled PWM outputs can be selected on the
CT16B0_MAT[2:0] outputs. For timer 1, two single-edged PWM outputs can be selected
on the CT16B1_Mat[1:0] outputs. One additional match register determines the PWM
cycle length. When a match occurs in any of the other match registers, the PWM output is
set to HIGH. The timer is reset by the match register that is configured to set the PWM
cycle length. When the timer is reset to zero, all currently HIGH match outputs configured
as PWM outputs are cleared.
Table 293. PWM Control Register (TMR16B0PWMC - address 0x4000 C074 and
TMR16B1PWMC- address 0x4001 0074)
0 PWMEN0 PWM channel0 enable 0
0 CT16Bn_MAT0 is controlled by EM0.
1 PWM mode is enabled for CT16Bn_MAT0.
1 PWMEN1 PWM channel1 enable 0
0 CT16Bn_MAT1 is controlled by EM1.
1 PWM mode is enabled for CT16Bn_MAT1.
2 PWMEN2 PWM channel2 enable 0
0 Match channel 2 or pin CT16B0_MAT2 is controlled by
EM2. Match channel 2 is not pinned out on timer 1.
1 PWM mode is enabled for match channel 2 or pin
CT16B0_MAT2.
3 PWMEN3 PWM channel3 enable
Note: It is recommended to use match channel 3 to set
the PWM cycle because it is not pinned out.
0
0 Match channel 3 match channel 3 is controlled by EM3.
1 PWM mode is enabled for match channel 3match
channel 3.
31:4 - Reserved, user software should not write ones to
reserved bits. The value read from a reserved bit is not
defined.
18.7.13 Rules for single edge controlled PWM outputs
1. All single edge controlled PWM outputs go LOW at the beginning of each PWM cycle
(timer is set to zero) unless their match value is equal to zero.
2. Each PWM output will go HIGH when its match value is reached. If no match occurs
(i.e. the match value is greater than the PWM cycle length), the PWM output remains
continuously LOW.
3. If a match value larger than the PWM cycle length is written to the match register, and
the PWM signal is HIGH already, then the PWM signal will be cleared on the next start
of the next PWM cycle.
4. If a match register contains the same value as the timer reset value (the PWM cycle
length), then the PWM output will be reset to LOW on the next clock tick. Therefore,
the PWM output will always consist of a one clock tick wide positive pulse with a
period determined by the PWM cycle length (i.e. the timer reload value).
5. If a match register is set to zero, then the PWM output will go to HIGH the first time the
timer goes back to zero and will stay HIGH continuously.
Note: When the match outputs are selected to serve as PWM outputs, the timer reset
(MRnR) and timer stop (MRnS) bits in the Match Control Register MCR must be set to 0
except for the match register setting the PWM cycle length. For this register, set the
MRnR bit to 1 to enable the timer reset when the timer value matches the value of the
corresponding match register.
.END
*** LPC1114 Timers ***
3.5.14 System AHB clock control register
The AHBCLKCTRL register enables the clocks to individual system and peripheral blocks.
The system clock (sys_ahb_clk[0], bit 0 in the AHBCLKCTRL register) provides the clock
for the AHB to APB bridge, the AHB matrix, the ARM Cortex-M0, the Syscon block, and
the PMU. This clock cannot be disabled.
Table 20. System AHB clock divider register (SYSAHBCLKDIV, address 0x4004 8078)
7:0 DIV System AHB clock divider values 0x01
0: System clock disabled.
1: Divide by 1. to 255: Divide by 255.
Table 21. System AHB clock control register (SYSAHBCLKCTRL, address 0x4004 8080) 1
0 SYS Enables clock for AHB to APB bridge, to the AHB matrix, to the Cortex-M0 FCLK and HCLK, to the
SysCon, and to the PMU. This bit is read only.
0 Reserved
1 Enable
Table 79. IOCON_PIO0_8 register (IOCON_PIO0_8, address 0x4004 4060)
2:0 FUNC Selects pin function. All other values are reserved. 000
0x0 Selects function PIO0_8.
0x1 Selects function MISO0.
0x2 Selects function CT16B0_MAT0.
18.6 Pin description
Table 278 gives a brief summary of each of the counter/timer related pins.
18.7 Register description
The 16-bit counter/timer0 contains the registers shown in Table 279 and the 16-bit
counter/timer1 contains the registers shown in Table 280. More detailed descriptions
follow.
Table 278. Counter/timer pin description
Pin Type Description
CT16B0_CAP0
CT16B1_CAP0
Input Capture Signal:
A transition on a capture pin can be configured to load the Capture Register with the
value in the counter/timer and optionally generate an interrupt.
Counter/Timer block can select a capture signal as a clock source instead of the PCLK
derived clock. For more details see Section 18.7.11.
CT16B0_MAT[2:0]
CT16B1_MAT[1:0]
Output External Match Outputs of CT16B0/1:
When a match register of CT16B0/1 (MR3:0) equals the timer counter (TC), this output
can either toggle, go LOW, go HIGH, or do nothing. The External Match Register
(EMR) and the PWM Control Register (PWMCON) control the functionality of this
output.
18.7 Register description
The 16-bit counter/timer0 contains the registers shown in Table 279 and the 16-bit
counter/timer1 contains the registers shown in Table 280. More detailed descriptions
follow.
Table 279. Register overview: 16-bit counter/timer 0 CT16B0 (base address 0x4000 C000)
Name Access Address offset Description Reset value[1]
TMR16B0IR R/W 0x000 Interrupt Register (IR). The IR can be written to clear interrupts. The IR
can be read to identify which of five possible interrupt sources are
pending.
0
TMR16B0TCR R/W 0x004 Timer Control Register (TCR). The TCR is used to control the Timer
Counter functions. The Timer Counter can be disabled or reset through
the TCR.
0
TMR16B0TC R/W 0x008 Timer Counter (TC). The 16-bit TC is incremented every PR+1 cycles of
PCLK. The TC is controlled through the TCR.
0
TMR16B0PR R/W 0x00C Prescale Register (PR). When the Prescale Counter (below) is equal to
this value, the next clock increments the TC and clears the PC.
0
TMR16B0PC R/W 0x010 Prescale Counter (PC). The 16-bit PC is a counter which is incremented
to the value stored in PR. When the value in PR is reached, the TC is
incremented and the PC is cleared. The PC is observable and
controllable through the bus interface.
0
TMR16B0MCR R/W 0x014 Match Control Register (MCR). The MCR is used to control if an interrupt
is generated and if the TC is reset when a Match occurs.
0
TMR16B0MR0 R/W 0x018 Match Register 0 (MR0). MR0 can be enabled through the MCR to reset
the TC, stop both the TC and PC, and/or generate an interrupt every time
MR0 matches the TC.
0
TMR16B0MR1 R/W 0x01C Match Register 1 (MR1). See MR0 description. 0
TMR16B0MR2 R/W 0x020 Match Register 2 (MR2). See MR0 description. 0
TMR16B0MR3 R/W 0x024 Match Register 3 (MR3). See MR0 description. 0
TMR16B0CCR R/W 0x028 Capture Control Register (CCR). The CCR controls which edges of the
capture inputs are used to load the Capture Registers and whether or not
an interrupt is generated when a capture takes place.
0
TMR16B0CR0 RO 0x02C Capture Register 0 (CR0). CR0 is loaded with the value of TC when
there is an event on the CT16B0_CAP0 input.
0
TMR16B0EMR R/W 0x03C External Match Register (EMR). The EMR controls the match function
and the external match pins CT16B0_MAT[2:0].
0
- - 0x040 -
0x06C
reserved -
TMR16B0CTCR R/W 0x070 Count Control Register (CTCR). The CTCR selects between Timer and
Counter mode, and in Counter mode selects the signal and edge(s) for
counting.
0
TMR16B0PWMC R/W 0x074 PWM Control Register (PWMCON). The PWMCON enables PWM mode
for the external match pins CT16B0_MAT[2:0].
0
[1] Reset value reflects the data stored in used bits only. It does not include reserved bits content.
18.7.1 Interrupt Register (TMR16B0IR and TMR16B1IR)
The Interrupt Register (IR) consists of four bits for the match interrupts and one bit for the
capture interrupt. If an interrupt is generated then the corresponding bit in the IR will be
HIGH. Otherwise, the bit will be LOW. Writing a logic one to the corresponding IR bit will
reset the interrupt. Writing a zero has no effect.
.END
**************************************************************************
* LPC11xx.h V1.10 24 November 2010
* CMSIS Cortex-M0 Core Peripheral Access Layer Header File for LPC11xx
/*------------- System Control (SYSCON) --------------------------------------*/
typedef struct
{
__IO uint32_t SYSMEMREMAP; /*!< Offset: 0x000 (R/W) System memory remap Register */
__IO uint32_t PRESETCTRL; /*!< Offset: 0x004 (R/W) Peripheral reset control Register */
__IO uint32_t SYSPLLCTRL; /*!< Offset: 0x008 (R/W) System PLL control Register */
__I uint32_t SYSPLLSTAT; /*!< Offset: 0x00C (R/ ) System PLL status Register */
uint32_t RESERVED0[4];
__IO uint32_t SYSOSCCTRL; /*!< Offset: 0x020 (R/W) System oscillator control Register */
__IO uint32_t WDTOSCCTRL; /*!< Offset: 0x024 (R/W) Watchdog oscillator control Register */
__IO uint32_t IRCCTRL; /*!< Offset: 0x028 (R/W) IRC control Register */
uint32_t RESERVED1[1];
__I uint32_t SYSRSTSTAT; /*!< Offset: 0x030 (R/ ) System reset status Register */
uint32_t RESERVED2[3];
__IO uint32_t SYSPLLCLKSEL; /*!< Offset: 0x040 (R/W) System PLL clock source select Register */
__IO uint32_t SYSPLLCLKUEN; /*!< Offset: 0x044 (R/W) System PLL clock source update enable Register */
uint32_t RESERVED3[10];
__IO uint32_t MAINCLKSEL; /*!< Offset: 0x070 (R/W) Main clock source select Register */
__IO uint32_t MAINCLKUEN; /*!< Offset: 0x074 (R/W) Main clock source update enable Register */
__IO uint32_t SYSAHBCLKDIV; /*!< Offset: 0x078 (R/W) System AHB clock divider Register */
uint32_t RESERVED4[1];
__IO uint32_t SYSAHBCLKCTRL; /*!< Offset: 0x080 (R/W) System AHB clock control Register */
uint32_t RESERVED5[4];
__IO uint32_t SSP0CLKDIV; /*!< Offset: 0x094 (R/W) SSP0 clock divider Register */
__IO uint32_t UARTCLKDIV; /*!< Offset: 0x098 (R/W) UART clock divider Register */
__IO uint32_t SSP1CLKDIV; /*!< Offset: 0x09C (R/W) SSP1 clock divider Register */
uint32_t RESERVED6[1];
uint32_t RESERVED7[11];
__IO uint32_t WDTCLKSEL; /*!< Offset: 0x0D0 (R/W) WDT clock source select Register */
__IO uint32_t WDTCLKUEN; /*!< Offset: 0x0D4 (R/W) WDT clock source update enable Register */
__IO uint32_t WDTCLKDIV; /*!< Offset: 0x0D8 (R/W) WDT clock divider Register */
uint32_t RESERVED9[1];
__IO uint32_t CLKOUTCLKSEL; /*!< Offset: 0x0E0 (R/W) CLKOUT clock source select Register */
__IO uint32_t CLKOUTUEN; /*!< Offset: 0x0E4 (R/W) CLKOUT clock source update enable Register */
__IO uint32_t CLKOUTDIV; /*!< Offset: 0x0E8 (R/W) CLKOUT clock divider Register */
uint32_t RESERVED10[5];
__I uint32_t PIOPORCAP0; /*!< Offset: 0x100 (R/ ) POR captured PIO status 0 Register */
__I uint32_t PIOPORCAP1; /*!< Offset: 0x104 (R/ ) POR captured PIO status 1 Register */
uint32_t RESERVED11[11];
uint32_t RESERVED12[7];
__IO uint32_t BODCTRL; /*!< Offset: 0x150 (R/W) BOD control Register */
__IO uint32_t SYSTCKCAL; /*!< Offset: 0x154 (R/W) System tick counter calibration Register */
uint32_t RESERVED13[1];
uint32_t RESERVED14[5];
uint32_t RESERVED15[2];
uint32_t RESERVED16[34];
__IO uint32_t STARTAPRP0; /*!< Offset: 0x200 (R/W) Start logic edge control Register 0 */
__IO uint32_t STARTERP0; /*!< Offset: 0x204 (R/W) Start logic signal enable Register 0 */
__O uint32_t STARTRSRP0CLR; /*!< Offset: 0x208 ( /W) Start logic reset Register 0 */
__I uint32_t STARTSRP0; /*!< Offset: 0x20C (R/ ) Start logic status Register 0 */
__IO uint32_t STARTAPRP1; /*!< Offset: 0x210 (R/W) Start logic edge control Register 1 (LPC11UXX only) */
__IO uint32_t STARTERP1; /*!< Offset: 0x214 (R/W) Start logic signal enable Register 1 (LPC11UXX only) */
__O uint32_t STARTRSRP1CLR; /*!< Offset: 0x218 ( /W) Start logic reset Register 1 (LPC11UXX only) */
__I uint32_t STARTSRP1; /*!< Offset: 0x21C (R/ ) Start logic status Register 1 (LPC11UXX only) */
uint32_t RESERVED17[4];
__IO uint32_t PDSLEEPCFG; /*!< Offset: 0x230 (R/W) Power-down states in Deep-sleep mode Register */
__IO uint32_t PDAWAKECFG; /*!< Offset: 0x234 (R/W) Power-down states after wake-up from Deep-sleep mode Register*/
__IO uint32_t PDRUNCFG; /*!< Offset: 0x238 (R/W) Power-down configuration Register*/
uint32_t RESERVED18[110];
__I uint32_t DEVICE_ID; /*!< Offset: 0x3F4 (R/ ) Device ID Register */
} LPC_SYSCON_TypeDef;
/*------------- Pin Connect Block (IOCON) --------------------------------*/
typedef struct
{
__IO uint32_t PIO2_6; /*!< Offset: 0x000 (R/W) I/O configuration for pin PIO2_6 */
uint32_t RESERVED0[1];
__IO uint32_t PIO2_0; /*!< Offset: 0x008 (R/W) I/O configuration for pin PIO2_0/DTR/SSEL1 */
__IO uint32_t RESET_PIO0_0; /*!< Offset: 0x00C (R/W) I/O configuration for pin RESET/PIO0_0 */
__IO uint32_t PIO0_1; /*!< Offset: 0x010 (R/W) I/O configuration for pin PIO0_1/CLKOUT/CT32B0_MAT2 */
__IO uint32_t PIO1_8; /*!< Offset: 0x014 (R/W) I/O configuration for pin PIO1_8/CT16B1_CAP0 */
uint32_t RESERVED1[1];
__IO uint32_t PIO0_2; /*!< Offset: 0x01C (R/W) I/O configuration for pin PIO0_2/SSEL0/CT16B0_CAP0 */
__IO uint32_t PIO2_7; /*!< Offset: 0x020 (R/W) I/O configuration for pin PIO2_7 */
__IO uint32_t PIO2_8; /*!< Offset: 0x024 (R/W) I/O configuration for pin PIO2_8 */
__IO uint32_t PIO2_1; /*!< Offset: 0x028 (R/W) I/O configuration for pin PIO2_1/nDSR/SCK1 */
__IO uint32_t PIO0_3; /*!< Offset: 0x02C (R/W) I/O configuration for pin PIO0_3 */
__IO uint32_t PIO0_4; /*!< Offset: 0x030 (R/W) I/O configuration for pin PIO0_4/SCL */
__IO uint32_t PIO0_5; /*!< Offset: 0x034 (R/W) I/O configuration for pin PIO0_5/SDA */
__IO uint32_t PIO1_9; /*!< Offset: 0x038 (R/W) I/O configuration for pin PIO1_9/CT16B1_MAT0 */
__IO uint32_t PIO3_4; /*!< Offset: 0x03C (R/W) I/O configuration for pin PIO3_4 */
__IO uint32_t PIO2_4; /*!< Offset: 0x040 (R/W) I/O configuration for pin PIO2_4 */
__IO uint32_t PIO2_5; /*!< Offset: 0x044 (R/W) I/O configuration for pin PIO2_5 */
__IO uint32_t PIO3_5; /*!< Offset: 0x048 (R/W) I/O configuration for pin PIO3_5 */
__IO uint32_t PIO0_6; /*!< Offset: 0x04C (R/W) I/O configuration for pin PIO0_6/SCK0 */
__IO uint32_t PIO0_7; /*!< Offset: 0x050 (R/W) I/O configuration for pin PIO0_7/nCTS */
__IO uint32_t PIO2_9; /*!< Offset: 0x054 (R/W) I/O configuration for pin PIO2_9 */
__IO uint32_t PIO2_10; /*!< Offset: 0x058 (R/W) I/O configuration for pin PIO2_10 */
__IO uint32_t PIO2_2; /*!< Offset: 0x05C (R/W) I/O configuration for pin PIO2_2/DCD/MISO1 */
__IO uint32_t PIO0_8; /*!< Offset: 0x060 (R/W) I/O configuration for pin PIO0_8/MISO0/CT16B0_MAT0 */
__IO uint32_t PIO0_9; /*!< Offset: 0x064 (R/W) I/O configuration for pin PIO0_9/MOSI0/CT16B0_MAT1 */
__IO uint32_t SWCLK_PIO0_10; /*!< Offset: 0x068 (R/W) I/O configuration for pin SWCLK/PIO0_10/SCK0/CT16B0_MAT2 */
__IO uint32_t PIO1_10; /*!< Offset: 0x06C (R/W) I/O configuration for pin PIO1_10/AD6/CT16B1_MAT1 */
__IO uint32_t PIO2_11; /*!< Offset: 0x070 (R/W) I/O configuration for pin PIO2_11/SCK0 */
__IO uint32_t R_PIO0_11; /*!< Offset: 0x074 (R/W) I/O configuration for pin TDI/PIO0_11/AD0/CT32B0_MAT3 */
__IO uint32_t R_PIO1_0; /*!< Offset: 0x078 (R/W) I/O configuration for pin TMS/PIO1_0/AD1/CT32B1_CAP0 */
__IO uint32_t R_PIO1_1; /*!< Offset: 0x07C (R/W) I/O configuration for pin TDO/PIO1_1/AD2/CT32B1_MAT0 */
__IO uint32_t R_PIO1_2; /*!< Offset: 0x080 (R/W) I/O configuration for pin nTRST/PIO1_2/AD3/CT32B1_MAT1 */
__IO uint32_t PIO3_0; /*!< Offset: 0x084 (R/W) I/O configuration for pin PIO3_0/nDTR */
__IO uint32_t PIO3_1; /*!< Offset: 0x088 (R/W) I/O configuration for pin PIO3_1/nDSR */
__IO uint32_t PIO2_3; /*!< Offset: 0x08C (R/W) I/O configuration for pin PIO2_3/RI/MOSI1 */
__IO uint32_t SWDIO_PIO1_3; /*!< Offset: 0x090 (R/W) I/O configuration for pin SWDIO/PIO1_3/AD4/CT32B1_MAT2 */
__IO uint32_t PIO1_4; /*!< Offset: 0x094 (R/W) I/O configuration for pin PIO1_4/AD5/CT32B1_MAT3 */
__IO uint32_t PIO1_11; /*!< Offset: 0x098 (R/W) I/O configuration for pin PIO1_11/AD7 */
__IO uint32_t PIO3_2; /*!< Offset: 0x09C (R/W) I/O configuration for pin PIO3_2/nDCD */
__IO uint32_t PIO1_5; /*!< Offset: 0x0A0 (R/W) I/O configuration for pin PIO1_5/nRTS/CT32B0_CAP0 */
__IO uint32_t PIO1_6; /*!< Offset: 0x0A4 (R/W) I/O configuration for pin PIO1_6/RXD/CT32B0_MAT0 */
__IO uint32_t PIO1_7; /*!< Offset: 0x0A8 (R/W) I/O configuration for pin PIO1_7/TXD/CT32B0_MAT1 */
__IO uint32_t PIO3_3; /*!< Offset: 0x0AC (R/W) I/O configuration for pin PIO3_3/nRI */
__IO uint32_t SCK_LOC; /*!< Offset: 0x0B0 (R/W) SCK pin location select Register */
__IO uint32_t DSR_LOC; /*!< Offset: 0x0B4 (R/W) DSR pin location select Register */
__IO uint32_t DCD_LOC; /*!< Offset: 0x0B8 (R/W) DCD pin location select Register */
__IO uint32_t RI_LOC; /*!< Offset: 0x0BC (R/W) RI pin location Register */
} LPC_IOCON_TypeDef;
/*------------- General Purpose Input/Output (GPIO) --------------------------*/
typedef struct
{
union {
__IO uint32_t MASKED_ACCESS[4096]; /*!< Offset: 0x0000 (R/W) Port data Register for pins PIOn_0 to PIOn_11 */
struct {
uint32_t RESERVED0[4095];
__IO uint32_t DATA; /*!< Offset: 0x3FFC (R/W) Port data Register */
};
};
uint32_t RESERVED1[4096];
__IO uint32_t DIR; /*!< Offset: 0x8000 (R/W) Data direction Register */
__IO uint32_t IS; /*!< Offset: 0x8004 (R/W) Interrupt sense Register */
__IO uint32_t IBE; /*!< Offset: 0x8008 (R/W) Interrupt both edges Register */
__IO uint32_t IEV; /*!< Offset: 0x800C (R/W) Interrupt event Register */
__IO uint32_t IE; /*!< Offset: 0x8010 (R/W) Interrupt mask Register */
__I uint32_t RIS; /*!< Offset: 0x8014 (R/ ) Raw interrupt status Register */
__I uint32_t MIS; /*!< Offset: 0x8018 (R/ ) Masked interrupt status Register */
__O uint32_t IC; /*!< Offset: 0x801C ( /W) Interrupt clear Register */
} LPC_GPIO_TypeDef;
/*------------- Timer (TMR) --------------------------------------------------*/
typedef struct
{
__IO uint32_t IR; /*!< Offset: 0x000 (R/W) Interrupt Register */
__IO uint32_t TCR; /*!< Offset: 0x004 (R/W) Timer Control Register */
__IO uint32_t TC; /*!< Offset: 0x008 (R/W) Timer Counter Register */
__IO uint32_t PR; /*!< Offset: 0x00C (R/W) Prescale Register */
__IO uint32_t PC; /*!< Offset: 0x010 (R/W) Prescale Counter Register */
__IO uint32_t MCR; /*!< Offset: 0x014 (R/W) Match Control Register */
__IO uint32_t MR0; /*!< Offset: 0x018 (R/W) Match Register 0 */
__IO uint32_t MR1; /*!< Offset: 0x01C (R/W) Match Register 1 */
__IO uint32_t MR2; /*!< Offset: 0x020 (R/W) Match Register 2 */
__IO uint32_t MR3; /*!< Offset: 0x024 (R/W) Match Register 3 */
__IO uint32_t CCR; /*!< Offset: 0x028 (R/W) Capture Control Register */
__I uint32_t CR0; /*!< Offset: 0x02C (R/ ) Capture Register 0 */
uint32_t RESERVED1[3];
__IO uint32_t EMR; /*!< Offset: 0x03C (R/W) External Match Register */
uint32_t RESERVED2[12];
__IO uint32_t CTCR; /*!< Offset: 0x070 (R/W) Count Control Register */
__IO uint32_t PWMC; /*!< Offset: 0x074 (R/W) PWM Control Register */
} LPC_TMR_TypeDef;
/******************************************************************************/
/* Peripheral memory map */
/******************************************************************************/
/* Base addresses */
#define LPC_FLASH_BASE (0x00000000UL)
#define LPC_RAM_BASE (0x10000000UL)
#define LPC_APB0_BASE (0x40000000UL)
#define LPC_AHB_BASE (0x50000000UL)
/* APB0 peripherals */
#define LPC_CT16B0_BASE (LPC_APB0_BASE + 0x0C000)
#define LPC_CT16B1_BASE (LPC_APB0_BASE + 0x10000)
#define LPC_CT32B0_BASE (LPC_APB0_BASE + 0x14000)
#define LPC_CT32B1_BASE (LPC_APB0_BASE + 0x18000)
#define LPC_IOCON_BASE (LPC_APB0_BASE + 0x44000)
#define LPC_SYSCON_BASE (LPC_APB0_BASE + 0x48000)
/* AHB peripherals */
#define LPC_GPIO_BASE (LPC_AHB_BASE + 0x00000)
#define LPC_GPIO0_BASE (LPC_AHB_BASE + 0x00000)
#define LPC_GPIO1_BASE (LPC_AHB_BASE + 0x10000)
#define LPC_GPIO2_BASE (LPC_AHB_BASE + 0x20000)
#define LPC_GPIO3_BASE (LPC_AHB_BASE + 0x30000)
/******************************************************************************/
/* Peripheral declaration */
/******************************************************************************/
#define LPC_TMR16B0 ((LPC_TMR_TypeDef *) LPC_CT16B0_BASE)
#define LPC_TMR16B1 ((LPC_TMR_TypeDef *) LPC_CT16B1_BASE)
#define LPC_TMR32B0 ((LPC_TMR_TypeDef *) LPC_CT32B0_BASE)
#define LPC_TMR32B1 ((LPC_TMR_TypeDef *) LPC_CT32B1_BASE)
#define LPC_IOCON ((LPC_IOCON_TypeDef *) LPC_IOCON_BASE )
#define LPC_SYSCON ((LPC_SYSCON_TypeDef *) LPC_SYSCON_BASE)
#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE )
#define LPC_GPIO1 ((LPC_GPIO_TypeDef *) LPC_GPIO1_BASE )
#define LPC_GPIO2 ((LPC_GPIO_TypeDef *) LPC_GPIO2_BASE )
#define LPC_GPIO3 ((LPC_GPIO_TypeDef *) LPC_GPIO3_BASE )
.END
Example
Reference: UM10398 LPC11xx Usert Manual 24 September 2012
Chapter 7: LPC1100/LPC1100C/LPC1100L series: I/O configuration (IOCONFIG)
7.3.1 Pin function
The FUNC bits in the IOCON registers can be set to GPIO (FUNC = 000) or to a peripheral function. If the pins are GPIO pins, the GPIOnDIR registers determine whether
the pin is configured as an input or output (see Section 12.3.2).
For any peripheral function, the pin direction is controlled automatically depending on the pin’s functionality.
The GPIOnDIR registers have no effect for peripheral functions.
Table 56. I/O configuration registers ordered by port number
Port pin Register name
PIO0_0 IOCON_RESET_PIO0_0
PIO0_1 IOCON_PIO0_1
PIO0_2 IOCON_PIO0_2
PIO0_3 IOCON_PIO0_3
PIO0_4 IOCON_PIO0_4
PIO0_5 IOCON_PIO0_5
PIO0_6 IOCON_PIO0_6
PIO0_7 IOCON_PIO0_7
PIO0_8 IOCON_PIO0_8
PIO0_9 IOCON_PIO0_9
PIO0_10 IOCON_SWCLK_PIO0_10
PIO0_11 IOCON_R_PIO0_11
PIO1_0 IOCON_R_PIO1_0
PIO1_1 IOCON_R_PIO1_1
PIO1_2 IOCON_R_PIO1_2
PIO1_3 IOCON_SWDIO_PIO1_3
PIO1_4 IOCON_PIO1_4
PIO1_5 IOCON_PIO1_5
PIO1_6 IOCON_PIO1_6
PIO1_7 IOCON_PIO1_7
PIO1_8 IOCON_PIO1_8
PIO1_9 IOCON_PIO1_9
PIO1_10 IOCON_PIO1_10
PIO1_11 IOCON_PIO1_11
PIO2_0 IOCON_PIO2_0
PIO2_1 IOCON_PIO2_1
PIO2_2 IOCON_PIO2_2
PIO2_3 IOCON_PIO2_3
PIO2_4 IOCON_PIO2_4
PIO2_5 IOCON_PIO2_5
PIO2_6 IOCON_PIO2_6
PIO2_7 IOCON_PIO2_7
PIO2_8 IOCON_PIO2_8
PIO2_9 IOCON_PIO2_9
PIO2_10 IOCON_PIO2_10
PIO2_11 IOCON_PIO2_11
PIO3_0 IOCON_PIO3_0
PIO3_1 IOCON_PIO3_1
PIO3_2 IOCON_PIO3_2
PIO3_3 IOCON_PIO3_3
PIO3_4 IOCON_PIO3_4
PIO3_5 IOCON_PIO3_5
- IOCON_SCK_LOC
- IOCON_DSR_LOC
- IOCON_DCD_LOC
- IOCON_RI_LOC
7.4.4 IOCON_PIO0_1
2:0 FUNC Selects pin function. All other values are reserved. 000
0x0 Selects function PIO0_1.
0x1 Selects function CLKOUT.
0x2 Selects function CT32B0_MAT2.
4:3 MODE Selects function mode (on-chip pull-up/pull-down resistor control). 10
0x0 Inactive (no pull-down/pull-up resistor enabled).
0x1 Pull-down resistor enabled.
0x2 Pull-up resistor enabled.
0x3 Repeater mode.
*** Example - Blink Xia Board LEDs ***
*** Xia Board LEDs ***
ledPortPinArrayArray XiaLedPortPinArrayArray = {{Port1, Pin8}, {Port2, Pin7}, {Port2, Pin8}, {Port2, Pin5}};
*** GPIO port setting ***
Ref: UM10398
Table 61. IOCON_PIO1_8 register (IOCON_PIO1_8, address 0x4004 4014)
2:0 FUNC Selects pin function. All other values are reserved. 000
0x0 Selects function PIO1_8.
0x1 Selects function CT16B1_CAP0.
4:3 MODE Selects function mode (on-chip pull-up/pull-down resistor control). 10
0x0 Inactive (no pull-down/pull-up resistor enabled).
0x1 Pull-down resistor enabled.
0x2 Pull-up resistor enabled.
0x3 Repeater mode.
Table 63. IOCON_PIO2_7 register (IOCON_PIO2_7, address 0x4004 4020)
2:0 FUNC Selects pin function. All other values are reserved. 000
0x0 Selects function PIO2_7.
4:3 MODE Selects function mode (on-chip pull-up/pull-down resistor control).
0x0 Inactive (no pull-down/pull-up resistor enabled).
0x1 Pull-down resistor enabled.
0x2 Pull-up resistor enabled.
0x3 Repeater mode.
Table 64. IOCON_PIO2_8 register (IOCON_PIO2_8, address 0x4004 4024)
2:0 FUNC Selects pin function. All other values are reserved. 000
0x0 Selects function PIO2_8.
4:3 MODE Selects function mode (on-chip pull-up/pull-down resistor control).
0x0 Inactive (no pull-down/pull-up resistor enabled).
0x1 Pull-down resistor enabled.
0x2 Pull-up resistor enabled.
0x3 Repeater mode.
Table 72. IOCON_PIO2_5 register (IOCON_PIO2_5, address 0x4004 4044)
2:0 FUNC Selects pin function. All other values are reserved.
0x0 Selects function PIO2_5.
4:3 MODE Selects function mode (on-chip pull-up/pull-down resistor control).
0x0 Inactive (no pull-down/pull-up resistor enabled).
0x1 Pull-down resistor enabled.
0x2 Pull-up resistor enabled.
0x3 Repeater mode.
7.4.23 IOCON_PIO0_8
Table 79. IOCON_PIO0_8 register (IOCON_PIO0_8, address 0x4004 4060)
bit description
Bit Symbol Value Description Reset value
2:0 FUNC Selects pin function. All other values are reserved. 000
0x0 Selects function PIO0_8.
0x1 Selects function MISO0.
0x2 Selects function CT16B0_MAT0.
4:3 MODE Selects function mode (on-chip pull-up/pull-down resistor control). 10
0x0 Inactive (no pull-down/pull-up resistor enabled).
0x1 Pull-down resistor enabled.
0x2 Pull-up resistor enabled.
0x3 Repeater mode.
5 HYS Hysteresis.
0 Disable.
1 Enable.
9:6 - - Reserved
10 OD Selects pseudo open-drain mode. See Section 7.1 for part specific details.
0 Standard GPIO output
1 Open-drain output
31:11 - - Reserved
7.4.4 IOCON_PIO0_1
Table 60. IOCON_PIO0_1 register (IOCON_PIO0_1, address 0x4004 4010)
2:0 FUNC Selects pin function. All other values are reserved. 000
0x0 Selects function PIO0_1.
0x1 Selects function CLKOUT.
0x2 Selects function CT32B0_MAT2.
4:3 MODE Selects function mode (on-chip pull-up/pull-down resistor control). 10
0x0 Inactive (no pull-down/pull-up resistor enabled).
0x1 Pull-down resistor enabled.
0x2 Pull-up resistor enabled.
0x3 Repeater mode.
5 HYS Hysteresis. 0
0 Disable.
1 Enable.
9:6 - - Reserved 0011
10 OD Selects pseudo open-drain mode. See Section 7.1 for part specific details. 0
0 Standard GPIO output
1 Open-drain output
31:11 - - Reserved -
*** Timer Example 1 ***
LPC_SYSCON ->SYSAHBCLKCTRL |= (1 << 8); // Enable Clock for TMR1
LPC_IOCON ->PIO1_9 |= (1 << 0); // PIN1_9 = CT16B1_MAT0
LPC_TMR16B1 ->MR0 = 2000; // 50% Duty Cycle
LPC_TMR16B1 ->PR = 12000;
LPC_TMR16B1 ->MR3 = 4000; // Cycle Length
LPC_TMR16B1 ->MCR |= (1 << 10); // TC Reset on MR3 Match
LPC_TMR16B1 ->PWMC |= (1 << 0); // PWM Mode
LPC_TMR16B1 ->TCR |= (1 << 0); // GO
Timer Example 2
// LPC_IOCON->PIO0_8
// I/O configuration for pin PIO0_8/MISO0/CT16B0_MAT0 (R/W)
struct _PIO0_8
{
uint32_t FUNC : 3; // pin function
uint32_t MODE : 2; // pull up/down resistor mode
uint32_t HYS : 1; // Hysteresis.
uint32_t reserved0 : 4;
uint32_t OD : 1; // Selects pseudo open-drain mode
uint32_t reserved1 : 21;
};
Use inline functions to cast the ptr to register to the structure and then set/get the bit field values.
#define PIO0_8_FUNC_GPIO 0x0
#define PIO0_8_FUNC_MISO 0x1
#define PIO0_8_FUNC_TIMER 0x2
inline void IOCON_PIO0_8_FUNC(uint32_t val)
{
((_PIO0_8*)&LPC_IOCON->PIO0_8)->FUNC = val;
}
Let the compiler figure out all of the masks and bit shifts for me.
Here is what programming the 16-bit timer for PWM looks like with these inline functions:
void SetupPWM()
{
// Enables clock for 16-bit counter/timer 0
SYSCON_SYSAHBCLKCTRL_CT16B0(SYSAHBCLKCTRL_ENABLE);
// setup pin 1 for PWM output
IOCON_PIO0_8_FUNC(PIO0_8_FUNC_TIMER);
// disable pullup resistor pin 1
IOCON_PIO0_8_MODE(PIO0_8_MODE_NO_RESISTOR);
// set timer prescaler
TMR16B0_PR_Set(SystemFrequency/10000); // TC = 10Khz
// set match register 3 to reset TC
TMR16B0_MCR_MR3R(MCR_ENABLE);
// set PWM duty cycle
TMR16B0_MR3_Set(100); // 100Hz
// set pulse width
TMR16B0_MR0_Set(0); // 0%
// enable PWM mode on match register 0 (MR0)
TMR16B0_PWMC_PWMEN0(PWMC_ENABLE);
// enable counter
TMR16B0_TCR_CEn(TCR_ENABLE);
// reset timers
//TMR16B0_TCR_CRst(TCR_RESET);
}
*** Systick example 1 ***
uint32_t SystemFrequency;
extern "C" void SystemInit(void)
volatile unsigned long SysTickCnt; // SysTick Counter
// SysTick Interrupt Handler (1ms)
extern "C" void SysTick_Handler(void)
{
SysTickCnt++;
}
void Delay(unsigned long tick)
{
unsigned long systickcnt;
systickcnt = SysTickCnt;
// TODO: handle when SysTickCnt overflows
while ((SysTickCnt - systickcnt) < tick);
}
int main(void)
{
// Set system frequency to 48MHz
SystemFrequency = ConfigurePLL(12000000UL, 48000000UL);
// Enable clock to IO Configuration block. Needed for UART, SPI, I2C, etc...
SYSCON_SYSAHBCLKCTRL_IOCON(SYSAHBCLKCTRL_ENABLE);
SysTick_Config(SystemFrequency/1000 - 1); // Generate interrupt each 1 ms
// set direction on port 0_7 (pin 28) to output
GPIO0_DIR(7, GPIO_OUTPUT);
while (1)
{
int j;
for (j = 0; j < 10; ++j)
{
Delay(50);
GPIO0_DATA(7, 1); // turn on LED on pin 28
Delay(50);
GPIO0_DATA(7, 0); // turn off LED
}
Delay(1000);
}
}
*** NXP Blinky 01/18/2010 v1.0 ***
/* Includes ------------------------------------------------------------------*/
#include "LPC11xx.h" /* LPC11xx definitions */
#include "timer16.h"
#include "clkconfig.h"
#include "gpio.h"
extern volatile uint32_t timer16_0_counter;
extern volatile uint32_t timer16_1_counter;
#define TEST_TIMER_NUM 0 /* 0 or 1 for 16-bit timers only */
int main (void) {
SystemInit();
/* Config CLKOUT, mostly used for debugging. */
CLKOUT_Setup( CLKOUTCLK_SRC_MAIN_CLK );
LPC_IOCON->PIO0_1 &= ~0x07;
LPC_IOCON->PIO0_1 |= 0x01; /* CLK OUT */
/* Enable AHB clock to the GPIO domain. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
/* TEST_TIMER_NUM is either 0 or 1 for 16-bit timer 0 or 1. */
init_timer16(TEST_TIMER_NUM, TIME_INTERVAL);
enable_timer16(TEST_TIMER_NUM);
/* Set port 2_0 to output */
GPIOSetDir( 2, 9, 1 );
while (1) /* Loop forever */
{
#if TEST_TIMER_NUM
/* I/O configuration and LED setting pending. */
if ( (timer16_1_counter > 0) && (timer16_1_counter <= 200) )
{
GPIOSetValue( 2, 9, 0 );
}
if ( (timer16_1_counter > 200) && (timer16_1_counter <= 400) )
{
GPIOSetValue( 2, 9, 1 );
}
else if ( timer16_1_counter > 400 )
{
timer16_1_counter = 0;
}
#else
/* I/O configuration and LED setting pending. */
if ( (timer16_0_counter > 0) && (timer16_0_counter <= 200) )
{
GPIOSetValue( 2, 9, 0 );
}
if ( (timer16_0_counter > 200) && (timer16_0_counter <= 400) )
{
GPIOSetValue( 2, 9, 1 );
}
else if ( timer16_0_counter > 400 )
{
timer16_0_counter = 0;
}
#endif
}
}
.END
No comments:
Post a Comment