I’m struggling to setup SPI on Socket 9 from RLP on the CobraII. I’m using Simon’s EmBlock template but cannot seem to relate the header file to the manual where it’s talking about the ‘IOCON’ registers.
I’ve been through Codeshare looking for examples but could not find ant examples for the G120.
Could someone please point me in the right direction?
After spending the whole weekend trying to get this one simple step achieved I’m at the point of admitting defeat!
I’m using the following to configure the port on Socket 9
LPC_SC->PCONP |= 1 <<21; //enable POWER to SSP0 (redundant following reset)
LPC_SC->PCLKSEL1 |= 1<<10; //pclk = cclk so should now be 120MHz on the G120
LPC_SSP0->CPSR |= 30; //Internal divider which should yield 4Mhz SCLK for 120Mhz pclk
LPC_PINCON->PINSEL0 |= 0x02 << 30; // Set Pin P0.15 to function 3 = SCLK
LPC_PINCON->PINSEL1 |= 0x02<<2; // Set Pin P0.17 to function 3 = MISO
LPC_PINCON->PINSEL1 |= 0x02<<4; // Set Pin P0.18 to function 3 = MOSI
LPC_SSP0->CR0 |= 3<<6; // CPOL = 1, CPHA = 1
LPC_SSP0->CR0 |= 7<<0; // 8 bit transfer
LPC_SSP0->CR1 |= 1<<1; //enable SSP
but it still not playing ball.
In desperation I resorted to peeking the contents of the IOCON register values (0x4002C03C, 0x4002C044 & 0x4002C048) for SCLK, MISO & MOSI from the managed side and can see that they do not change from their default values of 0xB0 when I try configuring the port but if I create the port on the managed side the values change to 0xA2.
All I can think is that I must be making a basic error somewhere but I feel like I’m just going around in circles now. :wall:
@ Sprigo - you are right about the power bit . I have an example using spi1. maybe it helps
#define SSP1CPSR (*(volatile unsigned long *)(0x40030010)) // SPI1 Clock Prescale Register
#define SSP1CR0 (*(volatile unsigned long *)(0x40030000)) // SPI1 Control register 0
#define SSP1CR1 (*(volatile unsigned long *)(0x40030004)) // SPI1 Control register 1
#define SSP1DR (*(volatile unsigned long *)(0x40030008)) // SPI1 data register
#define SSP1IMSC (*(volatile unsigned long *)(0x40030014)) // SPI1 Interrupt Mask Set and Clear Register
#define SSP1SR (*(volatile unsigned long *)(0x4003000C)) // SPI1 Status Register
typedef struct
{
union {
unsigned long _u32;
struct {
unsigned long FUNC:3;
unsigned long MODE:2;
unsigned long HYS:1;
unsigned long INV:1;
unsigned long b7:1; // must be set to 1 for normal operation
unsigned long SLEW:1;
unsigned long OD:1;
unsigned long Res2:22;
};
};
} IOCON_W;
ypedef struct
{
union {
volatile unsigned long _u32;
struct {
volatile unsigned long LCD:1;
volatile unsigned long TIM0:1;
volatile unsigned long TIM1:1;
volatile unsigned long UART0:1;
volatile unsigned long UART1:1;
volatile unsigned long PWM0:1;
volatile unsigned long PWM1:1;
volatile unsigned long I2C0:1;
volatile unsigned long UART4:1;
volatile unsigned long RTC:1;
volatile unsigned long SPI1:1;
volatile unsigned long EMC:1;
volatile unsigned long ADC:1;
volatile unsigned long CAN1:1;
volatile unsigned long CAN2:1;
volatile unsigned long GPIO:1;
volatile unsigned long RES:1;
volatile unsigned long MCPWM:1;
volatile unsigned long QE1:1;
volatile unsigned long I2C1:1;
volatile unsigned long SPI2:1;
volatile unsigned long SPI0:1;
volatile unsigned long TIM2:1;
volatile unsigned long TIM3:1;
volatile unsigned long UART2:1;
volatile unsigned long UART3:1;
volatile unsigned long I2C2:1;
volatile unsigned long I2S:1;
volatile unsigned long SDCard:1;
volatile unsigned long GPDMA:1;
volatile unsigned long ENET:1;
volatile unsigned long USB:1;
};
};
} PCONP_CONTROL;
typedef struct
{
union {
volatile unsigned long _u32;
struct {
unsigned long DSS:4; // Data Size Select
unsigned long FRF:2; // Frame format
unsigned long CPOL:1; // Clock Out Polarity
unsigned long CPHA:1; // Clock Out Phase
unsigned long SCR:1; // Serial Clock Rate
unsigned long res:27; // not used
};
};
} SPI_CONTROL_REGISTER_0;
// Set the functions of the used SPI pins
IOCON_W iocon_w = {{ 0 }};
iocon_w.FUNC = 2;
iocon_w.b7 = 1;
IOCON_P0_07 = iocon_w._u32; // SPI1 CLK -->
IOCON_P0_08 = iocon_w._u32; // SPI1 MISO <-- in MCU
IOCON_P0_09 = iocon_w._u32; // SPI1 MOSI --> out MCU
PCONP_CONTROL powerControl = { {0} };
powerControl.SPI1 = 1;
PCONP |= powerControl._u32;
// Set SPI1 mode
SPI_CONTROL_REGISTER_0 spi1Ctrl0 = {{ 0 }};
spi1Ctrl0.DSS = 7; // 8 bit data, SPI frame format, CPOL = 0, CPHA = 0
SSP1CR0 = spi1Ctrl0._u32;
SSP1CPSR = _spi_LowClock;
SSP1IMSC = 0x00; // disable interrupts
@ Sprigo - I do not have a G120 based device so I cannot actually test this. Looking at the user manual, some of the code you have here does not look correct. Esp. the clock related stuff.
It also looks like you are using the <LPC17xx.h> header file, for this chip I think you should rather be using the <LPC177x_8x.h> header file, then it would give you IOCON structure which is (IMHO) easier to translate from the MCU’s user manual
This is my first foray into RLP and after a whole weekend just going around in circles and being on the verge of scrapping the project (frustration had set in ) the relief at getting this simple step working is fantastic.
The peripheral clock (PCLK) drives the peripheral bus (APB). To calculate your SPI frequency you set the Clock Prescale Register (CPSR) to a value that will divide the peripheral clock down to the desired clock frequency for the SPI peripheral, this is the clock that will be used to clock the peripheral, you then further divide this clock by the Serial Clock Rate (SCR) in the CR0 register to yield the final SPI frequency.
You can use the following formula to calculate the SPI frequency
freq = PCLK / (CPSR * (SCR + 1))
You will need to know the PCLK frequency to calculate the desired SPI frequency, I would not recommend you try change this as this has a system wide effect. Either GHI can tell you the frequency or if you have a logic analyzer you can plug in a few values for CPSR and SCR then measure the SPI frequency, you then have everything you need to transpose the formula and calculate what frequency the PCLK is running at. If I had a G120 I would happily do this for you, I just went and added a G120 to my cart, lived long enough without one now…
All the above was gleaned from the user manual, any errors are probably in my interpretation of that information. I referenced the following sections
3.3.22 Peripheral Clock Selection Register
21.6.1 SSPn Control Register 0 (See bits 15:8 SCR it includes the formula above)
21.6.5 SSPn Clock Prescale Register
Thanks for the information @ taylorza. It was the frequency of PCLK that I couldn’t find anywhere but I didn’t realise that it was set by GHI. Unfortunately I don’t have a logic analyzer so took the rather dubious route of increasing the prescaler until I could communicate and then added a bit more. :whistle:
I must have a trawl of fleaBay and see if I can’t find a cheap logic analyzer.
Since you do not have a logic analyzer, you can also read the registers to determine the configuration.
CCLKSEL[4:0] will give you the divide used for the CPU clock, you can use this info to determine the sysclk frequency. I suspect this might be 1, giving a sysclk freq of 120Mhz, but I would double check.
PCLKSEL[4:0] will give you the PCLK divide value that is used to divide the sysclk frequency to give you PCLK.
Btw. I would be interested to know what your findings are if you do the above.
@ Sprigo - Have you any working RLP C code you could share to setup SPI and Read/Write some bytes?
All I need to do is set it up, and then write/read 2 bytes with an G120 based board.