⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 l3dev.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
字号:
/*----------------------------------------------------------------------
 * Copyright (C) 1999 Intel Corp.
 *
 * This file contains the GPIO based L3 control object. This object
 * provides control of Philips L3 type devices. This device requires a
 * GPIO object to set and clear the clock, data and mode pins.
 *
 * Note: The L3 pins are shared with I2C devices. This should not present
 * any problems as long as an I2C start sequence is not generated. This is
 * defined as a 1->0 transition on the data lines when the clock is high.
 * It is critical this this code only allow data transitions when the clock
 * is low. This is always legal in L3.
 *
 * The IIC interface requires the clock and data pin to be LOW when idle. We
 * must make sure we leave them in this state.
 *
 * It appears the read data is generated on the falling edge of the clock
 * and should be held stable during the clock high time.
 */


#include <windows.h>
#include <types.h>
#include "sa11x0.h"
#include "macros.h"





#define GetGPIO(bit) 	 ((*(volatile unsigned *)&lv_pGPIOReg->gplr >> bit) & 1)
#define SetGPIO(bit)     (*(volatile unsigned *)&lv_pGPIOReg->gpsr |= (1 << bit))
#define ClearGPIO(bit)   (*(volatile unsigned *)&lv_pGPIOReg->gpcr |= (1 << bit))
#define  InputGPIO(bit)  (*(volatile unsigned *)&lv_pGPIOReg->gpdr |= (1 << bit))
#define OutputGPIO(bit)    (*(volatile unsigned *)&lv_pGPIOReg->gpdr &= ~(1 << bit))


/* Define the setup and hold times
 */
#define L3_DataSetupTime 1 /* 190 ns */
#define L3_DataHoldTime  1 /*  30 ns */
#define L3_ModeSetupTime 1 /* 190 ns */
#define L3_ModeHoldTime  1 /* 190 ns */
#define L3_ClockHighTime 100 /* 250 ns (min is 64*fs, 35us @ 44.1 Khz) */
#define L3_ClockLowTime  100 /* 250 ns (min is 64*fs, 35us @ 44.1 Khz) */
#define L3_HaltTime      1 /* 190 ns */

#define L3Wait(tim) usWait(tim)

void usWait(unsigned usVal);
void msWait(unsigned msVal);

volatile struct gpioreg *lv_pGPIOReg = NULL;


// default values
int  L3_ClockPin = 18;
int  L3_ModePin = 17;
int  L3_DataPin = 15;



/*----------------------------------------------------------------------
 * Grab control of the IIC/L3 shared pins
 */
static
void acquirePins(void)
{
  SetGPIO(L3_ClockPin);
  SetGPIO(L3_DataPin);

  OutputGPIO(L3_ClockPin);
  OutputGPIO(L3_DataPin);
}

/*----------------------------------------------------------------------
 * Release control of the IIC/L3 shared pins
 */
static
void releasePins(void)
{
  InputGPIO(L3_ClockPin);
  InputGPIO(L3_DataPin);

  ClearGPIO(L3_ClockPin);
  ClearGPIO(L3_DataPin);
}



/*----------------------------------------------------------------------
 * init function
 * 
 */

void l3_Init(volatile struct gpioreg *pGPIOReg, int dataPin, int clockPin, int modePin)
{

  lv_pGPIOReg = pGPIOReg;
 

  L3_ClockPin = clockPin;
  L3_ModePin = modePin;
  L3_DataPin = dataPin;

}

/*----------------------------------------------------------------------
 * Get a bit. The clock is high on entry and on exit. Data is read after
 * the clock low time has expired.
 */
static
int l3getBit(void)
{
  int data;

  ClearGPIO(L3_ClockPin);
  L3Wait(L3_ClockLowTime);

  data = GetGPIO(L3_DataPin);

  SetGPIO(L3_ClockPin);
  L3Wait(L3_ClockHighTime);

  return data;
}

/*----------------------------------------------------------------------
 * Send a bit. The clock is high on entry and on exit. Data is sent only
 * when the clock is low (I2C compatibility).
 */
static
void l3sendBit( int bit)
{
  ClearGPIO(L3_ClockPin);

  if (bit&1) {
    SetGPIO(L3_DataPin);
  }
  else {
    ClearGPIO(L3_DataPin);
  }

  L3Wait(L3_ClockLowTime); /* Assumes L3_DataSetupTime < L3_ClockLowTime */

  SetGPIO(L3_ClockPin);
  L3Wait(L3_ClockHighTime);
}

/*----------------------------------------------------------------------
 * Send a byte. The mode line is set or pulsed based on the mode sequence
 * count. The mode line is high on entry and exit. The mod line is pulsed
 * before the second data byte and before ech byte thereafter.
 */
static
void l3sendByte(char data, int mode)
{
  int i;

  //acquirePins();

  switch(mode) {
  case 0: /* Address mode */
    ClearGPIO(L3_ModePin);
    break;
  case 1: /* First data byte */
    break;
  default: /* Subsequent bytes */
    ClearGPIO(L3_ModePin);
    L3Wait(L3_HaltTime);
    SetGPIO(L3_ModePin);
    break;
  }

  L3Wait(L3_ModeSetupTime);

  for (i=0; i < 8; i++)
    l3sendBit(data >> i);

  if (mode == 0) /* Address mode */
    SetGPIO(L3_ModePin);

  L3Wait(L3_ModeHoldTime);

  //releasePins();

}

/*----------------------------------------------------------------------
 * Write data to a device on the L3 bus. The address is passed as well as
 * the data and length. The length written is returned. The register space
 * is encoded in the address (low two bits are set and devicve address is
 * in the upper 6 bits).
 */

int l3write(char addr, char * data, int len)
{
  int mode = 0;
  int bytes = len;

  l3sendByte(addr, mode++);
  while(len--)
    l3sendByte(*data++, mode++);

  return bytes;
}

/*----------------------------------------------------------------------
 * Get a byte. The mode line is set or pulsed based on the mode sequence
 * count. The mode line is high on entry and exit. The mod line is pulsed
 * before the second data byte and before each byte thereafter. This
 * function is never valid with mode == 0 (address cycle) as the address
 * is always sent on the bus, not read.
 */
static
char l3getByte(int mode)
{
  char data = 0;
  int i;

  //acquirePins();

  switch(mode) {
  case 0: /* Address mode - never valid */
    break;
  case 1: /* First data byte */
    break;
  default: /* Subsequent bytes */
    ClearGPIO(L3_ModePin);
    L3Wait(L3_HaltTime);
    SetGPIO(L3_ModePin);
    break;
  }

  L3Wait(L3_ModeSetupTime);

  for (i=0; i < 8; i++)
    data |= (l3getBit() << i);

  L3Wait(L3_ModeHoldTime);

  //releasePins();
  return data;
}


/*----------------------------------------------------------------------
 * Read data from a device on the L3 bus. The address is passed as well as
 * the data and length. The length read is returned. The register space
 * is encoded in the address (low two bits are set and devicve address is
 * in the upper 6 bits).
 */
static
int l3read( char addr, char * data, int len)
{
  int mode = 0;
  int bytes = len;

  l3sendByte(addr, mode++);
  while(len--)
    *data++ =l3getByte(mode++);

  return bytes;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -