|
Hardware

»
Gumstix

SSP Internal Clock Division (PXA270)

View:
Threaded Chronologically All
Messages

New views

5 Messages — Rating Filter: 0
1
2 3
4
5
Alert me

SSP Internal Clock Division (PXA270)

by

ajg112

:: Rate this Message:

Reply to Author

| View
Threaded | Show
Only this Message

Hi,

I'm using the
PXA270 SSP Serial Port. I'm having trouble dividing down the internal
13MHz clock source to generate slower clock rates. (I'm using port 2)

Whatever I set SCR to, SSPSCLK2 always clocks at 13MHz. Is it
possible to use the scaler for the internal clock source, or is it just
for use with the external clock source?

Attached is my source
file.

Thanks
Andy

Re: SSP Internal Clock Division (PXA270)

by

ajg112

:: Rate this Message:

Reply to Author

| View
Threaded | Show
Only this Message

Sorry, seems the upload
didn't do anything

#include <fcntl.h>
#include
<stdio.h>
#include <stdlib.h>
#include
<inttypes.h>
#include <sys/mman.h>

// PXA270
Register Summary (Page 507)
#define MAP_SIZE 4096
#define MAP_MASK
(MAP_SIZE-1)

#define GPIO_REGISTERS 0x40E00000 // GPIO Registers

#define PXA270_GPDR0 0x40E0000C // Page 1004
#define
PXA270_GAFR0_L 0x40E00054 // Page 1016
#define PXA270_GAFR0_U
0x40E00058 // Page 1017

#define CLOCKS_REGISTERS 0x41300000 //
Clocks Manager Registers
#define PXA270_CKEN 0x41300004 // Page 176

#define NSSP2_REGISTERS 0x41700000 // NSSP2 Registers
#define
PXA270_SSCR0_2 0x41700000 // Page 479
#define PXA270_SSCR1_2
0x41700004 // Page 484
#define PXA270_SSSR_2 0x41700008 // Page 497
SSP 2 Status Register
#define PXA270_SSDR_2 0x41700010 // Page 501 SSP
2 Data Read/Write Register

void *initialiseMap(int fd, int var);

uint32_t getMem(uint32_t addr, void *map);
static void
putMem(uint32_t addr, void *map, uint32_t val);
void setupPort(int
fd);

int main(void)
{

printf("Start SSP Test\n");

// Open

int fd = open("/dev/mem", O_RDWR |
O_SYNC);

if (fd<0) {

perror("open(\"/dev/mem\")");

exit(1);
}

setupPort(fd);

void *map = initialiseMap(fd, NSSP2_REGISTERS);

int dataOut = 10000;

printf("PXA270_SSSR_2 = 0x%08X\n", getMem(PXA270_SSSR_2, map));

while (dataOut)

{

while ((getMem(PXA270_SSSR_2, map) >> 8) & 0xF); // Wait
for Tx FIFO Level to reach 0

putMem(PXA270_SSDR_2, map, dataOut);

dataOut--;

}

munmap(0,MAP_SIZE);

return 0;
}

void
setupPort(int fd)
{
void *map;

int i;

// Setup Clock
// -----------

map = initialiseMap(fd, CLOCKS_REGISTERS);

// Clock Enable Register (Page 176)

i = getMem(PXA270_CKEN, map);

i &= ~(1<<3); // Bit 3 CKEN3 (Clock Enable
3), Clear SSP2 Unit Clock Enable

putMem(PXA270_CKEN, map, i);

printf("PXA270_CKEN = 0x%08X\n", getMem(PXA270_CKEN, map));

// Set Port Pin Directions & Alternate Functions

//
---------------------------------------------

map = initialiseMap(fd, GPIO_REGISTERS);

// GPIO Pin-Direction Register 0 (Page 1004)

i = getMem(PXA270_GPDR0, map);

i = i & ~(1 << 11); // Bit 11 SSPRXD2, Input = 0

i = i | (1 << 13); // Bit 13
SSPTXD2, Output = 1
i = i | (1 <<
14); // Bit 14 SSPSFRM2, Output = 1
i = i
| (1 << 19); // Bit 19 SSPSCLK2, Output = 1

putMem(PXA270_GPDR0, map, i);

printf("PXA270_GPDR0 = 0x%08X\n", getMem(PXA270_GPDR0, map));

// GPIO Alternate Function Register 0
Lower (Page 1017)
i =
getMem(PXA270_GAFR0_L, map);
i = (i &
~(3<<22)) | (2<<22); // Bit 23:22 AF11 (Alternate Function
11), Function 2 - SSPRXD2
i = (i &
~(3<<28)) | (1<<28); // Bit 27:26 AF13 (Alternate Function
13), Function 1 - SSPTXD2
i = (i &
~(3<<28)) | (2<<28); // Bit 29:28 AF14 (Alternate Function
14), Function 2 - SSPSFRM2

putMem(PXA270_GAFR0_L, map, i);

printf("PXA270_GAFR0_L = 0x%08X\n", getMem(PXA270_GAFR0_L, map));

// GPIO Alternate Function Register 0
Upper (Page 1016)
i =
getMem(PXA270_GAFR0_U, map);
i = (i &
~(3<<6)) | (1<<6); // Bit 7:6 AF19 (Alternate Function 19),
Function 2 - SSPSCLK2

putMem(PXA270_GAFR0_U, map, i);

printf("PXA270_GAFR0_U = 0x%08X\n", getMem(PXA270_GAFR0_U, map));

// Setup Synchronous Serial
Protocol Ports
//
---------------------------------------

map = initialiseMap(fd, NSSP2_REGISTERS);

// SSP 2 Control Register 1 (Page 484)

// Bit 31 TTELP TXD Tristate Enable on Last Phase 0 = SSPTXDx
becomes high impedance 1/2 clock after the clock edge that starts the LSB

// Bit 30 TTE TXD Tristate Enable 0 =
SSPTXDx does not become high impedance
//
Bit 29 EBCEI Enable Bit Count Error Interrupt 0 = Interrupt due to a bit
count error is disabled
// Bit 28 SCFR
Slave Clock Free Running 0 = SSPSCLKx is continuously running (Ignored if
not slave mode)
// Bit 27 ECRA Enable
Clock Request A 0 = Clock request from another SSP port is disabled

// Bit 26 ECRB Enable Clock Request B 0 =
Clock request from another SSP port is disabled

// Bit 25 SCLKDIR SSPSCLKx Direction 0 = Master mode, the port
generates SSPSCLKx internally, acts as the master, and drives SSPSCLKx

// Bit 24 SFRMDIR SSP Frame Direction 0 =
Master mode, the port generates SSPSFRMx internally, acts as the master
and drives SSPSFRMx
// Bit 23 RWOT Receive
Without Transmit 0 = Transmit/receive mode

// Bit 22 TRAIL Trailing Byte 0 = Processor based, Trailing bytes are
handled by the CPU.
// Bit 21 TSRE
Transmit Service Request Enable 0 = DMA service request is disabled and
the state of the transmit FIFO DMA service request is ignored.

// Bit 20 RSRE Receive Service Request Enable 0 = DMA
service request is disabled and the state of the SSSR_x[RFS] is ignored.

// Bit 19 TINTE Receiver Time-Out
Interrupt Enable 0 = Receiver time-out interrupts are disabled. The
interrupt is masked and the state of SSSR_x[TINT] is ignored by the
interrupt controller.
// Bit 18 PINTE
Peripheral Trailing Byte Interrupt Enable 0 = Peripheral trailing byte
interrupts are disabled. The interrupt is masked and the state of
SSSRx[PINT] is ignored by the interrupt controller.

// Bit 16 IFS Invert Frame Signal 0 = SSPSFRMx polarity is
determined by SSP format and PSP polarity bits.

// Bit 15 STRF Select FIFO for EFWR (test mode bit only) 0 =
Transmit FIFO is selected for both writes and reads through SSDR_x

// Bit 14 EFWR Enable FIFO Write/Read
(test mode bit) 0 = FIFO write/read special function is disabled (normal
SSP port operational mode)
// Bit 13:10
RFT Receive FIFO Threshold
// Bit 9:6 TFT
Transmit FIFO Threshold
// Bit 5 MWDS
Microwire Transmit Data Size 0 = 8-bit command word is transmitted.

// Bit 4 SPH Motorola SPI SSPSCLKx Phase 0
= SSPSCLKx is inactive one cycle at the start of a frame and 1/2 cycle at
the end of a frame.
// Bit 3 SPO Motorola
SPI SSPSCLKx Polarity 0 = SSPSCLKx is held low in the inactive or idle
state when the SSP port is not transmitting/receiving data.

// Bit 2 LBM Loop-Back Mode (test-mode bit only) 0 =
Normal SSP port operation is enabled.
//
Bit 1 TIE Transmit FIFO Interrupt Enable 0 = TX FIFO level interrupt is
disabled. The interrupt is masked and SSSR_x[TFS] is ignored.

// Bit 0 RIE Receive FIFO Interrupt Enable 0 = RX
FIFO level interrupt is disabled. The interrupt is masked and SSSR_x[RFS]
is ignored.
i = 0;

putMem(PXA270_SSCR1_2, map, i);

printf("PXA270_SSCR1_2 = 0x%08X\n", getMem(PXA270_SSCR1_2, map));

// SSP 2 Control Register 0 (Page 479)

// Bit 31 MOD Mode 0 = Normal SSP port
mode
// Bit 30 ACS Audio Clock Select 0 =
SSPSCLKx selection is determined by the NCS and ECS bits

// Bit 26:24 FRDC Frame Rate Divider Control

// Bit 23 TIM Transmit FIFO Underrun Interrupt Mask 0
= TX FIFO underrun events generate an SSP port interrupt.

// Bit 22 RIM Receive FIFO Overrun Interrupt Mask 0 =
RX FIFO overrun events generate an SSP port interrupt.

// Bit 21 NCS Network Clock Select 0 = The NCS bit
determines clock selection.
// Bit 20 EDSS
Extended Data Size Select 0 = Zero is pre-appended to the DSS value that
sets the DSS range from 4-16- bits.
// Bit
19:8 SCR Serial Clock Rate
// Bit 7 SSE
Synchronous Serial Enable 1 = SSP port operation enabled

// Bit 6 ECS External Clock Select 0 = On-chip clock
produces the SSP port SSPSCLKx.
// Bit 5:4
FRF Frame Format 0b01 = TI Synchronous Serial Protocol

// Bit 3:0 DSS Data Size Select 0b1111 = 16-bit data

i = 0;
i
|= (0xFFF<<8);
i |= (1<<7);

i |= (1<<4);

i |= 0xF;

putMem(PXA270_SSCR0_2, map, i);

printf("PXA270_SSCR0_2 = 0x%08X\n", getMem(PXA270_SSCR0_2, map));

// Setup Clock

// -----------
map =
initialiseMap(fd, CLOCKS_REGISTERS);

// Clock Enable Register (Page 176)
i =
getMem(PXA270_CKEN, map);
i |=
(1<<3); // Bit 3 CKEN3 (Clock Enable 3), Set SSP2 Unit Clock Enable

putMem(PXA270_CKEN, map, i);

printf("PXA270_CKEN = 0x%08X\n", getMem(PXA270_CKEN,
map));
}

void *initialiseMap(int fd, int var)
{

void *map = mmap( 0, // Address 0

MAP_SIZE, // Length in Bytes
4096

PROT_READ |
PROT_WRITE, // Protection Allow read and write

MAP_SHARED, // Flags Write references
change the underlying object

fd, // File Descriptor /dev/mem

var & ~MAP_MASK); // File Offset

if (map == (void*)-1 ) {

perror("mmap()");

exit(1);
}

return map;
}

static void putMem(uint32_t addr, void *map, uint32_t val)

{
uint32_t *regaddr = map + (addr & MAP_MASK);

*regaddr = val;
}

uint32_t getMem(uint32_t
addr, void *map)
{
uint32_t val;

val = *(uint32_t*) (map + (addr & MAP_MASK));
return
val;
}

Re: SSP Internal Clock Division (PXA270)

by

Dante Sanchez

:: Rate this Message:

Reply to Author

| View
Threaded | Show
Only this Message

Hi Andy,

ajg112 wrote:

I'm using the PXA270 SSP Serial Port. I'm
having trouble dividing down the internal 13MHz clock source to generate
slower clock rates. (I'm using port 2)

Whatever I set SCR to,
SSPSCLK2 always clocks at 13MHz. Is it possible to use the scaler for
the internal clock source, or is it just for use with the external clock
source?

Did you look at the SPI sample code in
the Buildroot website? You can find the example for the PXA270 if you
scroll down the page. Just look for "clockrate" in the code.

http://docwiki.gumstix.org/Sample_code/C/SPI

Dante

Re: SSP Internal Clock Division (PXA270)

by

ajg112

:: Rate this Message:

Reply to Author

| View
Threaded | Show
Only this Message

Dante Sanchez
wrote:

Did you look at the SPI sample code in the
Buildroot website? You can find the example for the PXA270 if you scroll
down the page. Just look for "clockrate" in the code.

Hi Dante,

That is what I based my code
on. I even tried adjusting the clock rate in the sample code and it didn't
seem to make any difference.

Andy

Re: SSP Internal Clock Division (PXA270)

by

ajg112

:: Rate this Message:

Reply to Author

| View
Threaded | Show
Only this Message

ajg112 wrote:

Whatever I set SCR to, SSPSCLK2 always clocks
at 13MHz. Is it possible to use the scaler for the internal clock
source, or is it just for use with the external clock source?

It turns out you need to disable the SSP port
before you change the value of the SCR (Serial Clock Rate).
So:
-
Clear bit 7 of PXA270_SSCR0_2       Disable Port
- Set
SCR of PXA270_SSCR0_2         Set Clock Rate
- Set
bit 7 of PXA270_SSCR0_2          Enable Port

So if you are adjusting the clock rate, recompiling then
executing, be sure to clear the enable bit before setting the value of
SCR.

Tryout this example: spiTest3.c

LightInTheBox - Buy
quality products at wholesale price

Free Forum Powered by Nabble

Forum Help