📄 ms_spi.c
字号:
/*******************************************************************************
* Mouse Sensor SPI communication library. *
* *
* Version: 02-02-2005 *
* *
* (C) 2005 Stephan Hengstler, Stanford Wireless Sensor Networks Lab *
*******************************************************************************/
#include <stdlib.h>
/* define signal bit masks */
const short MASK_NCS = 2;
const short MASK_NPD = 3;
const short MASK_MOSI = 1;
const short MASK_MISO = 8;
const short MASK_RESET = 4;
const short MASK_SCLK = 1;
/* prototypes of inpout32.dll functions */
short _stdcall Inp32(short port);
void _stdcall Out32(short port, short data);
/*******************************************************************************
* Function: Bit get. *
*******************************************************************************/
short bitget(short value, short bit)
{
short result;
/* get bit */
result = (value >> (bit - 1)) & 0x01;
/* return result */
return result;
}
/*******************************************************************************
* Function: Bit set/clear. *
*******************************************************************************/
short bitset(short value, short bit, short set)
{
short result;
/* clear bit? */
if (set == 0)
result = value & ((1 << (bit - 1)) ^ 0xff);
/* set bit? */
else if (set == 1)
result = value | (1 << (bit - 1));
/* otherwise */
else
result = value;
/* return result */
return result;
}
/*******************************************************************************
* Function: Read SPI register. *
*******************************************************************************/
short spi_read_register(short port, short address)
{
short bit, ctrl_value, data_value, dummy, value;
/* define port addresses */
const short DATA_PORT = port;
const short STAT_PORT = DATA_PORT + 1;
const short CTRL_PORT = DATA_PORT + 2;
/* set direction out */
ctrl_value = Inp32(CTRL_PORT);
ctrl_value = bitset(ctrl_value, 6, 0);
/* raise chip select */
ctrl_value = bitset(ctrl_value, MASK_NCS, 1);
Out32(CTRL_PORT, ctrl_value);
/* get data value */
data_value = Inp32(DATA_PORT);
/* address cycle */
for (bit = 8; bit > 0; bit--)
{
/* clear sclk */
ctrl_value = bitset(ctrl_value, MASK_SCLK, 1);
Out32(CTRL_PORT, ctrl_value);
/* place bit on mosi */
data_value = bitset(data_value, MASK_MOSI, bitget(address, bit));
Out32(DATA_PORT, data_value);
/* raise sclk */
ctrl_value = bitset(ctrl_value, MASK_SCLK, 0);
Out32(CTRL_PORT, ctrl_value);
}
/* insert delay per data sheet */
sleep(75e-3);
/* data cycle */
value = 0;
for (bit = 8; bit > 0; bit--)
{
/* clear sclk */
ctrl_value = bitset(ctrl_value, MASK_SCLK, 1);
Out32(CTRL_PORT, ctrl_value);
/* sense bit from miso */
dummy = (bitget(Inp32(STAT_PORT), MASK_MISO) ? 0 : 1);
value = bitset(value, bit, dummy);
/* raise sclk */
ctrl_value = bitset(ctrl_value, MASK_SCLK, 0);
Out32(CTRL_PORT, ctrl_value);
}
/* clear chip select */
ctrl_value = bitset(ctrl_value,MASK_NCS,0);
Out32(CTRL_PORT, ctrl_value);
/* return result */
return value;
}
/*******************************************************************************
* Function: Write SPI register. *
*******************************************************************************/
int spi_write_register(short port, short address, short value)
{
short bit, ctrl_value, data_value;
/* define port addresses */
const short DATA_PORT = port;
const short STAT_PORT = DATA_PORT + 1;
const short CTRL_PORT = DATA_PORT + 2;
/* set direction out */
ctrl_value = Inp32(CTRL_PORT);
ctrl_value = bitset(ctrl_value, 6, 0);
/* raise chip select */
ctrl_value = bitset(ctrl_value, MASK_NCS, 1);
Out32(CTRL_PORT, ctrl_value);
/* get data value */
data_value = Inp32(DATA_PORT);
/* address cycle */
address = bitset(address, 8, 1);
for (bit = 8; bit > 0; bit--)
{
/* clear sclk */
ctrl_value = bitset(ctrl_value, MASK_SCLK, 1);
Out32(CTRL_PORT, ctrl_value);
/* place bit on mosi */
data_value = bitset(data_value, MASK_MOSI, bitget(address, bit));
Out32(DATA_PORT, data_value);
/* raise sclk */
ctrl_value = bitset(ctrl_value, MASK_SCLK, 0);
Out32(CTRL_PORT, ctrl_value);
}
/* data cycle */
for (bit = 8; bit > 0; bit--)
{
/* clear sclk */
ctrl_value = bitset(ctrl_value, MASK_SCLK, 1);
Out32(CTRL_PORT, ctrl_value);
/* place bit on mosi */
data_value = bitset(data_value, MASK_MOSI, bitget(value, bit));
Out32(DATA_PORT, data_value);
/* raise sclk */
ctrl_value = bitset(ctrl_value, MASK_SCLK, 0);
Out32(CTRL_PORT, ctrl_value);
}
/* clear chip select */
ctrl_value = bitset(ctrl_value,MASK_NCS,0);
Out32(CTRL_PORT, ctrl_value);
/* return status */
return 1;
}
/*******************************************************************************
* Function: Mouse sensor frame capture. *
*******************************************************************************/
void ms_frame(short port, double *imager)
{
int status, x, y;
short bit, ctrl_value, data_value, dummy, pixel, value;
/* define mouse sensor registers */
const short MS_REG_FRAME_CAPTURE = 0x13; // Register: Frame capture.
const short MS_REG_PIXEL_BURST = 0x40; // Register: Pixel burst.
/* define mouse sensor parameters */
const int MS_IMG_WIDTH = 30; // Image array: Width.
const int MS_IMG_HEIGHT = 30; // Image array: Height.
/* define port addresses */
const short DATA_PORT = port;
const short STAT_PORT = DATA_PORT + 1;
const short CTRL_PORT = DATA_PORT + 2;
/* trigger frame capture */
status = spi_write_register(port, MS_REG_FRAME_CAPTURE, 0x83);
/* insert delay per data sheet */
sleep(3e-3);
/* set direction out */
ctrl_value = Inp32(CTRL_PORT);
ctrl_value = bitset(ctrl_value, 6, 0);
/* raise chip select */
ctrl_value = bitset(ctrl_value, MASK_NCS, 1);
Out32(CTRL_PORT, ctrl_value);
/* get data value */
data_value = Inp32(DATA_PORT);
/* address cycle */
for (bit = 8; bit > 0; bit--)
{
/* clear sclk */
ctrl_value = bitset(ctrl_value, MASK_SCLK, 1);
Out32(CTRL_PORT, ctrl_value);
/* place bit on mosi */
data_value = bitset(data_value, MASK_MOSI, bitget(MS_REG_PIXEL_BURST, bit));
Out32(DATA_PORT, data_value);
/* raise sclk */
ctrl_value = bitset(ctrl_value, MASK_SCLK, 0);
Out32(CTRL_PORT, ctrl_value);
}
/* insert delay per data sheet */
sleep(50e-3);
/* pixel burst read */
for (x = 0; x < MS_IMG_WIDTH; x++)
for (y = 0; y < MS_IMG_HEIGHT; y++)
{
/* data cycle */
value = 0;
for (bit = 8; bit > 0; bit--)
{
/* clear sclk */
ctrl_value = bitset(ctrl_value, MASK_SCLK, 1);
Out32(CTRL_PORT, ctrl_value);
/* sense bit from miso */
dummy = (bitget(Inp32(STAT_PORT), MASK_MISO) ? 0 : 1);
value = bitset(value, bit, dummy);
/* raise sclk */
ctrl_value = bitset(ctrl_value, MASK_SCLK, 0);
Out32(CTRL_PORT, ctrl_value);
}
/* mask pixel to 6 bit */
pixel = value & 63;
/* store pixel in image array */
imager[x*MS_IMG_WIDTH+y] = (double) pixel;
}
/* clear chip select */
ctrl_value = bitset(ctrl_value,MASK_NCS,0);
Out32(CTRL_PORT, ctrl_value);
/* return */
return;
}
/*******************************************************************************
* Function: Mouse sensor power up/down. *
*******************************************************************************/
int ms_power(short port, int state)
{
int status;
short ctrl_value;
/* define port addresses */
const short DATA_PORT = port;
const short STAT_PORT = DATA_PORT + 1;
const short CTRL_PORT = DATA_PORT + 2;
/* set direction out */
ctrl_value = Inp32(CTRL_PORT);
ctrl_value = bitset(ctrl_value, 6, 0);
/* clear reset */
ctrl_value = bitset(ctrl_value, MASK_RESET, 1);
/* valid power state? */
if ((state == 0) | (state == 1))
{
/* set power state */
ctrl_value = bitset(ctrl_value, MASK_NPD, state);
Out32(CTRL_PORT, ctrl_value);
/* insert delay per data sheet after power up */
if (state == 1)
sleep(590e-3);
/* return status */
status = 1;
}
/* unknown power state? */
else
{
/* return status */
status = -1;
}
/* return status */
return status;
}
/*******************************************************************************
* Function: Mouse sensor reset. *
*******************************************************************************/
int ms_reset(short port)
{
short ctrl_value;
/* define port addresses */
const short DATA_PORT = port;
const short STAT_PORT = DATA_PORT + 1;
const short CTRL_PORT = DATA_PORT + 2;
/* set direction out */
ctrl_value = Inp32(CTRL_PORT);
ctrl_value = bitset(ctrl_value, 6, 0);
/* raise reset */
ctrl_value = bitset(ctrl_value, MASK_RESET, 0);
Out32(CTRL_PORT, ctrl_value);
/* insert delay per data sheet */
sleep(10e-3);
/* clear reset */
ctrl_value = bitset(ctrl_value, MASK_RESET, 1);
Out32(CTRL_PORT, ctrl_value);
/* return status */
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -