Hi All,
Soon after I posted my question, I found the bug to my problem - but
had gone out of wireless modem range (a long story) so I have solved
the problem..
I'll post the code snippet anyway in case it is usefull for anyone else..
Regards
Kym
******************************
*
* Hardware Addresses specific to the TS7260/Tiris Gate
*/
/* regions which we need to remap to do I/O on */
#define TGIO_BASE GPIO_BASE
#define TGIO_LENGTH 0x10000ul
#define ADC_BASE 0x80900000ul
#define ADC_LENGTH 0x10000ul
#define SYS_BASE SYSCON_BASE
#define SYS_LENGTH 0x10000ul
/* #define SSP_BASE SSP_BASE */ /* already defined */
#define SSP_LENGTH 0x10000ul
/**************************************************************/
/* Bit Masks for TIRIS Gate I/O signals - Specific for TS7260 */
/* Note : Addresses come from
* include/asm-arm/arch-ep93xx/regmap.h */
volatile unsigned char *ssp_vbase;
/* this macro translates physical to virtual addresses */
#define ptov(vbase, addr) (vbase + (addr - GPIO_BASE))
#define TEMP_CS_DDR ptov(tgio_vbase, GPIO_PFDDR)
#define TEMP_CS_DR ptov(tgio_vbase, GPIO_PFDR)
#define TEMP_CS 0x04 /* DIO_16, PF2 - output - active low */
/***********************************/
/* System Control */
#define SYS_CLKSET1 (sys_vbase + (SYSCON_CLKSET1 -SYSCON_BASE))
#define SYS_KTDIV (sys_vbase + (SYSCON_KTDIV - SYSCON_BASE))
#define SYS_DEVCFG (sys_vbase + (SYSCON_DEVCFG - SYSCON_BASE))
#define SYS_SWLOCK (sys_vbase + (SYSCON_SWLOCK - SYSCON_BASE))
#define SYS_TSEN_BIT 0x80000000ul
#define UNLOCK 0x000000AAul
/***********************************/
/* Synchronous Serial Port - SSP */
#define SSP_CR0 (ssp_vbase + (SSPCR0 - SSP_BASE))
#define SSP_CR1 (ssp_vbase + (SSPCR1 - SSP_BASE))
#define SSP_DR (ssp_vbase + (SSPDR - SSP_BASE))
#define SSP_SR (ssp_vbase + (SSPSR - SSP_BASE))
#define SSP_CPSR (ssp_vbase + (SSPCPSR - SSP_BASE))
#define SSP_IIR (ssp_vbase + (SSPIIR - SSP_BASE))
/* Selected SSP_CR1 bits */
#define SSP_SSE_BIT 0x00000010ul
/* Selected SSP_CR0 bits */
#define SSP_DSS_16BIT 0x0000000Ful
/* Selected SSP_CPSR bits */
#define SSP_DVSR_254 0x000000FEul /* clock divisor */
/* Selected SSP_SR bits */
#define SSP_BSY_BIT 0x00000010ul /* Busy */
#define SSP_RFF_BIT 0x00000008ul /* RX FIFO Full */
#define SSP_RNE_BIT 0x00000004ul /* RX FIFO Not Empty */
#define SSP_TNF_BIT 0x00000002ul /* TX FIFO not full */
#define SSP_TFE_BIT 0x00000001ul /* TX FIFO Empty */
/* TMP124 Temp sensor commands */
#define TMP124_CMD_TEMP 0x8000
#define TMP124_DATA_N55 0xE487 /* -55 deg C */
#define TMP124_DATA_N0625 0xFFFF /* -0.0625 deg C */
#define TMP124_DATA_ZERO 0x0007 /* 0 deg C */
#define TMP124_DATA_P0625 0x000F /* +0.0625 deg C */
#define TMP124_DATA_P25 0x0C88 /* +25 deg C */
#define TMP124_DATA_P125 0x3E87 /* +125 deg C */
#define TMP124_DATA_P150 0x4B07 /* +150 deg C */
/*
* init the Synch Serial Port (for TMP124 temperature sensor & boot
EEPROM)
*/
void tg_init_ssp(void)
{
/* Set enable bit SSE */
writel(SSP_SSE_BIT, SSP_CR1);
/* write other SSP Config registers */
writel(SSP_DSS_16BIT, SSP_CR0);
writel(SSP_DVSR_254, SSP_CPSR);
/* clear SSE Bit */
writel(0x0, SSP_CR1);
/* set SSE Bit */
writel(SSP_SSE_BIT, SSP_CR1);
}
/*
* converts the raw TMP124 temperature into a signed int
* value, multiplied by 10000 (decimal point shifted 4 places to the
right)
*/
int reg2temp(short s)
{
s = s >> 3;
if ((s & 0x8000) == 0x8000)
{
/* temperature is negative - so 2's complement it */
s = -(~s + 1);
}
return (s * 625);
}
/*
* get temperature
*/
int get_temperature(void)
{
/* make Temp sensor chip select output low*/
writel(readl(TEMP_CS_DR) & ~TEMP_CS, TEMP_CS_DR);
writel(readl(TEMP_CS_DDR) | TEMP_CS, TEMP_CS_DDR);
/* send the read command on SPI bus */
writel(TMP124_CMD_TEMP, SSP_DR);
/* wait for transmission & reception of command - blocking */
while ((readl(SSP_SR) & SSP_BSY_BIT) == SSP_BSY_BIT);
/* disable chip select - set high */
writel(readl(TEMP_CS_DR) | TEMP_CS, TEMP_CS_DR);
return reg2temp(readl(SSP_DR) & 0xFFFF);
}
/* bit from main startup code */
/*****************************************/
/* Check memory region for SSP registers */
if (check_mem_region(SSP_BASE, SSP_LENGTH))
{
printk(KERN_ERR "Unable to acquire 0x%lX + 0x%lX for SSP_BASE\n",
(unsigned long)SSP_BASE, (unsigned long)SSP_LENGTH);
return 0;
}
request_mem_region(SSP_BASE, SSP_LENGTH, TG_MODULE_NAME);
/* call __ioremap */
ssp_vbase = (volatile unsigned char *)__ioremap(SSP_BASE,
SSP_LENGTH, 0);
--- In Curtis Monroe <> wrote:
>
> If you post the code, I'll take a look for any mistakes.
>
> -Curtis.
>
>
> On October 25, 2006 03:19 am, Kym Newbery wrote:
> > Hi everyone,
> >
> > I have been writing a kernel mode driver to access the TMP124 sensor
> > on a TS7260, using the user mode code examples I've seen on the
> > www.embeddedarm.com website as well this group. I've translated the
> > SSP initialisation and reading cycles to a kernel mode routine which
> > runs under interrupt, and passes data back to the user mode world via
> > ioctl calls.
> >
> > I have been having a lot of problems getting my driver to work with
> > the SSP/TMP124 in kernel mode, whereas the usermode examples work
> > fine, even though I have compared my kernel code to the examples on a
> > side by side basis and comparing how they tickle all the required port
> > I/O bits /etc..
> >
> > I am not able to get sensible results out of the TMP124/SSP in kernel
> > mode, and I often get 'exec format errors' in user mode land (that
> > last bit has me stumped..'.
> >
> > My question is, has anyone written any code to run in kernel mode
> > which accesses the TMP124?
> >
> > also, Are there any other functions in the kernel which access the
> > SSP periodically that my driver has to multiplex with?.. I have built
> > in the tsuart, usb modules into the kernel.
> >
> > My code also accesses all the GPIO ports, the EP93xx ADC and uses GPIO
> > interrupts - all of these work fine and reliably - it's just the
> > SSP/TMP124 interface which is giving me problems.
> >
> > In the process of writing the driver I have noticed that there are
> > some errors in the TS7260 schematic and potentially the Cirrus Logic
> > EP93xx users guide (??) with regards to port F, eg Port F is 3 bits
> > wide from bits 1 to 3 !! not 0 to 2 as you would expect.
> >
> > I am using bit 1 of Port F for other functions, which has made me
> > notice that most of the examples, when setting the TMP124 chip select
> > to active (zero) write 0x0 to port F data register rather than doing a
> > read-modify-write cycle only to clear the required CS# bit.
> >
> > I have seen these following posts :
> > http://tech.groups.yahoo.com/group/ts-7000/message/380
> >
> > and I have studied the example file "NewTempLogger.c" and the TS
> > temperature example in detail.. so I'm not a newbie at this..
> >
> > any ideas? or kernel mode code samples??
> >
> > Cheers
> > Kym
> > p.s. I am currently on a ship floating off the coast of Antarctica, so
> > my access to this group is very limited.. but I will get back to this
> > list in a week or two.
> >
> >
> >
>
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ts-7000/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/ts-7000/join
(Yahoo! ID required)
<*> To change settings via email:
<*> To unsubscribe from this group, send an email to:
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|