📄 l3dev.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 + -