Hi,
I have an Electrum100 board from Micromint and it has an SPI ADC (ADC128S052) hooked to the SPI1 with PC4 as CS.
I managed to start the SPI port (bit/clock/master settings and so on). Unfortunately, the CS would not toggle (it’s always low). The SPI_CLK and MOSI pins look just fine on the scope.
The code that I put together is given below:
/* user-land driver for external ADC on SPI1 CS2 (PC4)
Board: Electrum100 - Micromint, AT91SAM9G20
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>
#include "definitions.h"
#define MAP_SIZE 4096UL //4k
#define MAP_MASK (MAP_SIZE - 1)
#define SPI_PCS1(npcs) ((~(1 << npcs) & 0xF) << 16)
typedef unsigned char u08;
typedef signed char s08;
typedef unsigned short u16;
typedef signed short s16;
typedef unsigned long u32;
typedef signed long s32;
typedef unsigned long long u64;
typedef signed long long s64;
int fd, i, repetitions;
void *piob_base, *pioc_base, *spi1_base, *pmc_base, *aic_base;
// found on Atmel website
u16 spi_tx_rx(u32 TxData)
{
unsigned int RxData = 0;
//MASK UNUSED BITS
TxData &= 0x0000FFFF;
TxData|=SPI_PCS1(1)| AT91C_SPI_LASTXFER;
//WAIT UNTIL TRANSMIT REGISTER IS EMPTY
while (!(*((unsigned long *) (spi1_base+(AT91C_SPI1_SR & MAP_MASK))) & AT91C_SPI_TXEMPTY));
// TRANSMIT DATA
*((unsigned long *) (spi1_base+(AT91C_SPI1_TDR & MAP_MASK))) = TxData ;
//READ THE RECEIVED DATA
//WAIT UNTIL RECEIVE REGISTER IS FULL
while (!(*((unsigned long *) (spi1_base+(AT91C_SPI1_SR & MAP_MASK))) & AT91C_SPI_RDRF));
//READ RDR AND MASK UNUSED BITS
RxData = (*((unsigned long *) (spi1_base+(AT91C_SPI1_RDR & MAP_MASK))));
return (RxData&0xffff) ;
}
void open_controller(){
...
...
...
mmap() and error checking ...
}
int main() {
int buf[10000];
i=0;
open_controller();
// PMC setting
*((unsigned long *) (pmc_base+(AT91C_PMC_PCER & MAP_MASK))) = 1<<AT91C_ID_SPI1;
*((unsigned long *) (piob_base + (PIOB_PDR & MAP_MASK))) = AT91C_PB0_SPI1_MISO | AT91C_PB1_SPI1_MOSI | AT91C_PB2_SPI1_SPCK;
*((unsigned long *) (pioc_base + (PIOC_PDR & MAP_MASK))) = AT91C_PC4_SPI1_NPCS2_0;
// peripherals definitions
*((unsigned long *) piob_base + (PIOB_ASR & MAP_MASK)) = AT91C_PB0_SPI1_MISO | AT91C_PB1_SPI1_MOSI | AT91C_PB2_SPI1_SPCK;
*((unsigned long *) pioc_base + (PIOC_BSR & MAP_MASK)) = AT91C_PC4_SPI1_NPCS2_0;
// SPI1 setup
*((unsigned long *) (spi1_base+(AT91C_SPI1_CR & MAP_MASK))) = AT91C_SPI_SPIDIS;
*((unsigned long *) (spi1_base+(AT91C_SPI1_CR & MAP_MASK))) = AT91C_SPI_SWRST ;
*((unsigned long *) (spi1_base+(AT91C_SPI1_CR & MAP_MASK))) = AT91C_SPI_SPIEN | AT91C_SPI_LASTXFER ;
*((unsigned long *) (spi1_base+(AT91C_SPI1_MR & MAP_MASK))) = AT91C_SPI_MSTR | SPI_PCS1(1)|AT91C_SPI_PS_VARIABLE ;
*((unsigned long *) (spi1_base+(AT91C_SPI1_CSR1 & MAP_MASK))) = AT91C_SPI_NCPHA| AT91C_SPI_CPOL | AT91C_SPI_BITS_16 |0x6f<<8 ;
while(i<100000){
usleep(30);
printf("%lu \n",spi_tx_rx(1<<10));
i++;
}
*((unsigned long *) (spi1_base+(AT91C_SPI1_CR & MAP_MASK))) = AT91C_SPI_SPIDIS;
close(fd);
return 0;
}
Thanks a lot.