SparkFun Forums 

Where electronics enthusiasts find answers.

Everything ARM and LPC
By alexan_e
#132833
ARMwizard updated to version 2.0.3

There were a couple of bugs that had to be fixed and I didn't want to wait until the next version because they were limiting the functionality of the application, basically they affect the LPC17xx.

What is new

v2.0.3
• Fixed: the Pclock couldn't be set over 100MHz in LPC17xx ADC, now the limit is 200MHz [Johann Zimmermann]
• Fixed: in LPC17xx the Pclock divider is now common and can be set to 1/1 - 1/31


Visit
http://alexan.edaboard.eu/

Best regards
Alex
By William_Gaatjes
#132933
rmteo1 wrote:Have you guys seen this http://www.arm.com/products/processors/ ... /index.php
TEST-6F.jpg
I am aware that in the future the SAM7S series will be phased out of production. To be honest, i doubt the license for the mcu manufacturers to obtain the right to use an ARMv4T (ARM7) core is withdrawn by ARM. ARM just promotes the ARMV7 THUMB2 (CORTEX M3) core because it has advantages over ARMv4T.
The SAM3S is the replacement with a lot of key advantages. The same pinout as current SAM7S models. The same peripheral hardware with possible removed errate bugs present in current SAM7S hardware(Only minor issues that can be circumvented) . Only the core is different from the SAM3S. It is a CORTEX M3 as well with integrated interrupt hardware. Works very well. I am very fond of the ARM instructionset.
User avatar
By graynomad
#133541
Great tool Alex, I'm just getting into LPCs and I'm sure it will prove useful.

I found it when searching for a tool to help me select and allocate pins for a PCB design. With 208 to choose from most of which have 3-4 options it's a nightmare.

I'd love a tool that let's say I decide to use U1_RXD it at least shows me the pins that I can use but also maybe allows me to select one of them and highlight that I've already used that pins for T1_MAT0 or whatever.

Even better, give it a list of required functions and have it present a suggested pin list.

Any chance you could add that over the weekend :)

I don't suppose such a thing exists, I did see something similar the other day but it was commercial product and didn't support LPC chips anyway.

BTW, your web site has some strange behavior with Safari, the links highlight when the mouse is about 20mm about them, by chance that seems to be the height of the top frame so I suspect someone is using a frame pos rather than a screen pos or vv.
______
Rob
By alexan_e
#133551
Actually the application already does what you describe at least the first part (and not the pin sugestion)
If you click the quick selector button you will see that any enabled pin functions are shown with a checkbox so this serves as a quick review of the enabled pin functions.
Also in the function lists shown in the same menu you can see the pin number of each function inside the [ ] so when the same function exists in more than one pins you can see it there and select the one you want.
In addition if you click the function it will be automatically focused in the pin treeview in order to help you enable it quickly.

Alex
User avatar
By graynomad
#133581
Thanks Alex, yes I see that now. I'll have a play and see how it goes, it's certainly a lot better that what I've been doing.

With these complex chips I can't believe the manufacturers don't provide a tool like this.

One request, can you make the app window sizable?

______
Rob
By alexan_e
#133604
I have designed the application to be used in a non resizable form so even if you resize it you will either hide some of the components or you will see a lot of empty space, in either case I don't find this useful.
I know that there are a couple of settings lists that are shown with a height scroll bar but they should be convenient enough.

In which specific area would you find the sizable option useful?

Alex
#133610
Looks like an interesting tool. Have you thought about supporting the CMSIS standard. at least for register definitions.

I know this is a big change, as I've been converting our tools and examples to it. Almost ready to publish the results.

What CMSIS does at the low level is define register blocks as C structures. Whether this is good or bad can be open to debate.

But what is definitely good is that ARM and the vendors are publishing examples for their peripherals using these definitions. Unfortunately they haven't gone back to the ARM7 parts to do this in many cases, but for our examples we did a partial conversion.
By alexan_e
#133664
viskr wrote:Looks like an interesting tool. Have you thought about supporting the CMSIS standard. at least for register definitions.

I know this is a big change, as I've been converting our tools and examples to it. Almost ready to publish the results.

What CMSIS does at the low level is define register blocks as C structures. Whether this is good or bad can be open to debate.

But what is definitely good is that ARM and the vendors are publishing examples for their peripherals using these definitions. Unfortunately they haven't gone back to the ARM7 parts to do this in many cases, but for our examples we did a partial conversion.
I'm actually not familiar with it so I would have to learn what it is first and then try to apply it and I think it will be time consuming
I think I would rather focus on adding more features to the application (and probably more mcu like 13xx) but thank you for your suggestion.

Alex
#133667
You might want to look at CMSIS a bit more as it will help in adding new parts. The big difference will be how registers are defined. In older header files like LPC21xx.h and earlier LPC17xx.h you would see
Code: Select all
/* SPI0 (Serial Peripheral Interface 0) */
#define SPI0_BASE_ADDR		0x40020000
#define S0SPCR         (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x00))
#define S0SPSR         (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x04))
#define S0SPDR         (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x08))
#define S0SPCCR        (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x0C))
#define S0SPINT        (*(volatile unsigned long *)(SPI0_BASE_ADDR + 0x1C))
But in newer headers including LPC17xx.h from Keil or NXP you'll see
Code: Select all
typedef struct
{
  __IO uint32_t SPCR;
  __I  uint32_t SPSR;
  __IO uint32_t SPDR;
  __IO uint32_t SPCCR;
       uint32_t RESERVED0[3];
  __IO uint32_t SPINT;
} LPC_SPI_TypeDef;

#define LPC_SPI               ((LPC_SPI_TypeDef       *) LPC_SPI_BASE      )
So a register access goes from being
Code: Select all
S0SPCR=0x123;
to
Code: Select all
LPC_SPI->SPCR = 0x123;
Yes its a bit wordier, but in the future all header files delivered will be of this form. The best part is they now are in sync with the documentation, such that the user manual will call it by the same name as that one used in the header file. For a long time this was not always the case, and in fact much of the documentation is now done as XML so that headers are automatically generated from the user manual.

One other thing that has been added in Keil is some sort of meta script in the comments of system_LPCxxxx.c which can be used by their configuration wizard to set up clock and PLL registers. You might be able to leverage off that, and maybe extend it for port initialization.
By alexan_e
#133669
If CMSIS is to use the code format of your example (using structures) then my application already generates code for all LPC17xx chips this way, is this what you mean?
Code: Select all
/************************************************************************************
   Code created using the ARMwizard, visit http://alexan.edaboard.eu 
************************************************************************************/

#include LPC17xx.h>


/******************************************************************************
                  TIMER0 interrupt service function
******************************************************************************/
void TIMER0_IRQHandler(void) {
/* write code here */


/* list of all available flags, select which to use */
LPC_TIM0->IR = 1;   /* Clear MAT0.0 interrupt flag */
LPC_TIM0->IR = 2;   /* Clear MAT0.1 interrupt flag */
LPC_TIM0->IR = 4;   /* Clear MAT0.2 interrupt flag */
LPC_TIM0->IR = 8;   /* Clear MAT0.3 interrupt flag */
LPC_TIM0->IR = 16;  /* Clear CAP0.0 interrupt flag */
LPC_TIM0->IR = 32;  /* Clear CAP0.1 interrupt flag */
}

/******************************************************************************
                  EINT0 interrupt service function
******************************************************************************/
void EINT0_IRQHandler(void) {
/* write code here */


LPC_SC->EXTINT = 1;   /* Clear EINT0 interrupt flag */
}

/******************************************************************************
                  SPI interrupt service function
******************************************************************************/
void SPI_IRQHandler(void) {
/* write code here */


LPC_SPI->SPINT = 1;   /* Clear SPI interrupt flag */
}

int main(void)
{
/*
    P0.0:  PORT0.0 (General purpose I/O)  Output, pull-up resistor enabled
    P0.1:  PORT0.1 (General purpose I/O)  Output, pull-up resistor enabled
    P0.2:  PORT0.2 (General purpose I/O)  Input, repeater mode
    P0.3:  PORT0.3 (General purpose I/O)  Input, repeater mode, open drain
    P0.4:  PORT0.4 (General purpose I/O)  Input, pull-up resistor enabled
    P0.5:  PORT0.5 (General purpose I/O)  Input, pull-up resistor enabled
    P0.6:  PORT0.6 (General purpose I/O)  Input, neither pull-up nor pull-down
    P0.7:  PORT0.7 (General purpose I/O)  Input, neither pull-up nor pull-down
    P0.8:  PORT0.8 (General purpose I/O)  Input, pull-down resistor enabled, open drain
    P0.9:  PORT0.9 (General purpose I/O)  Input, pull-up resistor enabled
    P0.10:  PORT0.10 (General purpose I/O)  Input, pull-up resistor enabled
    P0.11:  PORT0.11 (General purpose I/O)  Input, pull-up resistor enabled
    P0.15:  PORT0.15 (General purpose I/O)  Input, pull-up resistor enabled
    P0.16:  PORT0.16 (General purpose I/O)  Input, pull-up resistor enabled, open drain
    P0.17:  PORT0.17 (General purpose I/O)  Input, pull-up resistor enabled
    P0.18:  PORT0.18 (General purpose I/O)  Input, pull-up resistor enabled
    P0.19:  PORT0.19 (General purpose I/O)  Input, pull-up resistor enabled
    P0.20:  PORT0.20 (General purpose I/O)  Input, pull-up resistor enabled
    P0.21:  PORT0.21 (General purpose I/O)  Input, pull-up resistor enabled
    P0.22:  PORT0.22 (General purpose I/O)  Input, pull-up resistor enabled
    P0.23:  PORT0.23 (General purpose I/O)  Input, pull-up resistor enabled
    P0.24:  PORT0.24 (General purpose I/O)  Input, pull-up resistor enabled
    P0.25:  PORT0.25 (General purpose I/O)  Input, pull-up resistor enabled
    P0.26:  PORT0.26 (General purpose I/O)  Input, pull-up resistor enabled
    P0.27:  PORT0.27 (General purpose I/open-drain O)  Input
    P0.28:  PORT0.28 (General purpose I/open-drain O)  Input
    P0.29:  PORT0.29 (General purpose I/O)  Input
    P0.30:  PORT0.30 (General purpose I/O)  Input
    P1.0:  PORT1.0 (General purpose I/O)  Input, pull-up resistor enabled
    P1.1:  PORT1.1 (General purpose I/O)  Input, pull-up resistor enabled
    P1.4:  PORT1.4 (General purpose I/O)  Input, pull-up resistor enabled
    P1.8:  PORT1.8 (General purpose I/O)  Input, pull-up resistor enabled
    P1.9:  PORT1.9 (General purpose I/O)  Input, pull-up resistor enabled
    P1.10:  PORT1.10 (General purpose I/O)  Input, pull-up resistor enabled
    P1.14:  PORT1.14 (General purpose I/O)  Input, pull-up resistor enabled
    P1.15:  PORT1.15 (General purpose I/O)  Input, pull-up resistor enabled
    P1.16:  PORT1.16 (General purpose I/O)  Input, pull-up resistor enabled
    P1.17:  PORT1.17 (General purpose I/O)  Input, pull-up resistor enabled
    P1.18:  PORT1.18 (General purpose I/O)  Input, pull-up resistor enabled
    P1.19:  PORT1.19 (General purpose I/O)  Input, pull-up resistor enabled
    P1.20:  PORT1.20 (General purpose I/O)  Input, pull-up resistor enabled
    P1.21:  PORT1.21 (General purpose I/O)  Input, pull-up resistor enabled
    P1.22:  PORT1.22 (General purpose I/O)  Input, pull-up resistor enabled
    P1.23:  PORT1.23 (General purpose I/O)  Input, pull-up resistor enabled
    P1.24:  PORT1.24 (General purpose I/O)  Input, pull-up resistor enabled
    P1.25:  PORT1.25 (General purpose I/O)  Input, pull-up resistor enabled
    P1.26:  PORT1.26 (General purpose I/O)  Input, pull-up resistor enabled
    P1.27:  PORT1.27 (General purpose I/O)  Input, pull-up resistor enabled
    P1.28:  PORT1.28 (General purpose I/O)  Input, pull-up resistor enabled
    P1.29:  PORT1.29 (General purpose I/O)  Input, pull-up resistor enabled
    P1.30:  PORT1.30 (General purpose I/O)  Input, pull-up resistor enabled
    P1.31:  PORT1.31 (General purpose I/O)  Input, pull-up resistor enabled
    P2.0:  PORT2.0 (General purpose I/O)  Input, pull-up resistor enabled
    P2.1:  PORT2.1 (General purpose I/O)  Input, pull-up resistor enabled
    P2.2:  PORT2.2 (General purpose I/O)  Input, pull-up resistor enabled
    P2.3:  PORT2.3 (General purpose I/O)  Input, pull-up resistor enabled
    P2.4:  PORT2.4 (General purpose I/O)  Input, pull-up resistor enabled
    P2.5:  PORT2.5 (General purpose I/O)  Input, pull-up resistor enabled
    P2.6:  PORT2.6 (General purpose I/O)  Input, pull-up resistor enabled
    P2.7:  PORT2.7 (General purpose I/O)  Input, pull-up resistor enabled
    P2.8:  PORT2.8 (General purpose I/O)  Input, pull-up resistor enabled
    P2.9:  PORT2.9 (General purpose I/O)  Input, pull-up resistor enabled
    P2.10:  PORT2.10 (General purpose I/O)  Input, pull-up resistor enabled
    P2.11:  PORT2.11 (General purpose I/O)  Input, pull-up resistor enabled
    P2.12:  PORT2.12 (General purpose I/O)  Input, pull-up resistor enabled
    P2.13:  PORT2.13 (General purpose I/O)  Input, pull-up resistor enabled
    P3.25:  PORT3.25 (General purpose I/O)  Input, pull-up resistor enabled
    P3.26:  PORT3.26 (General purpose I/O)  Input, pull-up resistor enabled
    P4.28:  PORT4.28 (General purpose I/O)  Input, pull-up resistor enabled
    P4.29:  PORT4.29 (General purpose I/O)  Input, pull-up resistor enabled
*/

    LPC_PINCON->PINSEL0=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINMODE0=0x0003A050;     /* binary: 00000000_00000011_10100000_01010000 */
    LPC_GPIO0->FIODIR=0x00000003;     /* binary: 00000000_00000000_00000000_00000011 */
    LPC_PINCON->PINMODE_OD0=0x00010108;     /* binary: 00000000_00000001_00000001_00001000 */
    LPC_PINCON->PINSEL1=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINMODE1=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINSEL2=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINMODE2=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_GPIO1->FIODIR=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINMODE_OD1=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINSEL3=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINMODE3=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINSEL4=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINMODE4=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_GPIO2->FIODIR=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINMODE_OD2=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINSEL7=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINMODE7=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_GPIO3->FIODIR=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINMODE_OD3=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINSEL9=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINMODE9=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_GPIO4->FIODIR=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_PINCON->PINMODE_OD4=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */

/******************************************************************************
                           External interrupts
*******************************************************************************
    Ext. interrupt 0 mode: Edge sensitivity / Rising edge
*/
    LPC_SC->EXTMODE=0x01;     /* binary: 00000001 */
    LPC_SC->EXTPOLAR=0x01;     /* binary: 00000001 */
    LPC_SC->EXTINT=0x01;     /* clear the external interrupt flags */

/******************************************************************************
                                       GPIO interrupts
*******************************************************************************
    P0.0 : On falling edge
    P0.1 : On falling edge
    P0.4 : On both edges
    P0.6 : On rising edge
*/
    LPC_GPIOINT->IO0IntEnR=0x00000050;     /* binary: 00000000_00000000_00000000_01010000 */
    LPC_GPIOINT->IO0IntEnF=0x00000013;     /* binary: 00000000_00000000_00000000_00010011 */
    LPC_GPIOINT->IO2IntEnR=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */
    LPC_GPIOINT->IO2IntEnF=0x00000000;     /* binary: 00000000_00000000_00000000_00000000 */

/******************************************************************************
                         Vectored Interrupt initialization
******************************************************************************/

   NVIC_EnableIRQ(TIMER0_IRQn);           /* Enable TIMER0 interrupt */
   NVIC_SetPriority(TIMER0_IRQn,0);          /* Default priority group 0, can be 0(highest) - 31(lowest) */

   NVIC_EnableIRQ(EINT0_IRQn);           /* Enable EINT0 interrupt */
   NVIC_SetPriority(EINT0_IRQn,0);          /* Default priority group 0, can be 0(highest) - 31(lowest) */

   NVIC_EnableIRQ(SPI_IRQn);           /* Enable SPI interrupt */
   NVIC_SetPriority(SPI_IRQn,0);          /* Default priority group 0, can be 0(highest) - 31(lowest) */

/******************************************************************************
                                           ADC0
*******************************************************************************
   ADC operational
   ADC clk: 3 MHz  (calculated with peripheral clock: 15MHz)
   ADC rate: 46,1538 Ksamples/sec
   manual mode, 60 clocks / 12 bit accuracy
   No start (only in manual mode, for burst always on)
   Channel 0 enabled, global DONE flag in ADGDR will generate an interrupt
   Channel 1 disabled, global DONE flag in ADGDR will generate an interrupt
   Channel 2 disabled, global DONE flag in ADGDR will generate an interrupt
   Channel 3 disabled, global DONE flag in ADGDR will generate an interrupt
   Channel 4 disabled, global DONE flag in ADGDR will generate an interrupt
   Channel 5 disabled, global DONE flag in ADGDR will generate an interrupt
   Channel 6 disabled, global DONE flag in ADGDR will generate an interrupt
   Channel 7 disabled, global DONE flag in ADGDR will generate an interrupt
*/

LPC_SC->PCONP |= 0x1000;      /* Enable peripheral clock for ADC (default is disabled) */
LPC_ADC->ADCR=0x00200401;     /* binary: 00000000_00100000_00000100_00000001 */
LPC_ADC->ADINTEN=0x00000100;     /* binary: 00000000_00000000_00000001_00000000 */

/******************************************************************************
                                 Timer0 (32bit)
*******************************************************************************
   Counter Disabled,    Counter Reset=0
   Timer mode: count on rising edge of PCLK
   Counter clk: 2 MHz, Counts every: 500 ns  (calculated with peripheral clock: 30MHz)
   MCR0.0 : generate interrupt on compare match
*/
LPC_TIM0->CTCR=0x00;     /* binary: 00000000 */
LPC_TIM0->TC=0x00000000;     /* decimal 0 */
LPC_TIM0->PR=0x0000000E;     /* decimal 14 */
LPC_TIM0->MCR=0x0001;     /* binary: 00000000_00000001 */
LPC_TIM0->MR0=0x000000C8;     /* decimal 200 */
LPC_TIM0->MR1=0x00000000;     /* decimal 0 */
LPC_TIM0->MR2=0x00000000;     /* decimal 0 */
LPC_TIM0->MR3=0x00000000;     /* decimal 0 */
LPC_TIM0->CCR=0x0000;     /* binary: 00000000_00000000 */
LPC_TIM0->EMR=0x0000;     /* binary: 00000000_00000000 */
LPC_TIM0->TCR=0x00;     /* binary: 00000000 */

   while(1)
  {
  
  
   }

}

Alex
#133670
You are already there, I was looking at version of code for the 21xx parts where the old style was in use.

With that being the case, I'll look harder into adding ARMwizard to our gcc based IDE for LPC21xx, LPC17xx, LPC11xx, LPC12xx and LPC13xx. We have made most of the conversion and also unified many of the common examples published from ARM for the peripherals.
By alexan_e
#133671
So far I have only included LPC21xx, 23xx, 24xx, 175x/6x and the latest 177x/8x that use the IOCON register.
I haven't included any LPC11xx, LPC12xx and LPC13xx but I will probaby add the 13xx at some point.

The register names that I use are the ones defined in the NXP datasheet and not the ones used by uvision which in some cases are different, whenever this is the case I use a set of defines so that the datasheet register names are translated to the ones used by uvision

for example in the generated code for LPC23xx I have included
Code: Select all
#define I2C0CONCLR I20CONCLR
#define I2C1CONCLR I21CONCLR
#define I2C2CONCLR I22CONCLR
#define INTCLEAR MAC_INTCLEAR
#define USBDevIntClr DEV_INT_CLR
#define USBEpIntClr EP_INT_CLR
#define USBDMARClr DMA_REQ_CLR
#define USBEoTIntClr EOT_INT_CLR
#define USBNDDRIntClr NDD_REQ_INT_CLR
#define USBSysErrIntClr SYS_ERR_INT_CLR
#define OTGIntClr OTG_INT_CLR
#define ILR RTC_ILR
#define IO0DIR IODIR0
#define IO1DIR IODIR1
#define MCIClear MCI_CLEAR
#define DMACIntClear GPDMA_INT_TCCLR
#define DMACIntErrClr GPDMA_INT_ERR_CLR
so in my code I use I2C0CONCLR as defined in the datasheet instead of the I20CONCLR which is defined in the keil header or INTCLEAR instead of MAC_INTCLEAR etc.

Alex