📄 spi.c
字号:
/*
* File : spi.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Develop Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://openlab.rt-thread.com/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2006-09-23 Vai first version (For ARM7TDMI core)
*/
#include "spi.h"
extern void swiDelay(unsigned int duration);
#define REG_SPI_CR (*(volatile unsigned short*)0x040001C0)
#define REG_SPI_DATA (*(volatile unsigned short*)0x040001C2)
#define SPI_4MHZ (0<<0)
#define SPI_2MHZ (1<<0)
#define SPI_1MHZ (2<<0)
#define SPI_512KHZ (3<<0)
#define SPI_BUSY (1<<7)
#define SPI_POWER (0<<8)
#define SPI_FIRMWARE (1<<8)
#define SPI_TOUCH (2<<8)
#define SPI_8CLOCKS (0<<10)
#define SPI_16CLOCKS (1<<10)
#define SPI_SINGLE (0<<11)
#define SPI_CONTINUOUS (1<<11)
#define SPI_INTERRUPT (1<<14)
#define SPI_ENABLE (1<<15)
#define POWER_READ (1<<7)
#define POWER_WRITE (0<<7)
#define POWER_REG(n) (n)
#define WAIT_FOR_NOT_BUSY() {while (REG_SPI_CR & SPI_BUSY) swiDelay(1);}
static unsigned short touch_read(unsigned int command)
{
unsigned short result;
WAIT_FOR_NOT_BUSY();
// Write the command and wait for it to complete
REG_SPI_CR = SPI_ENABLE | SPI_CONTINUOUS | SPI_TOUCH | SPI_8CLOCKS | SPI_2MHZ ;
REG_SPI_DATA = command;
WAIT_FOR_NOT_BUSY();
// Write the second command and clock in part of the data
REG_SPI_DATA = 0;
WAIT_FOR_NOT_BUSY();
result = REG_SPI_DATA;
// Clock in the rest of the data (last transfer)
REG_SPI_CR = SPI_ENABLE | SPI_SINGLE | SPI_TOUCH | SPI_8CLOCKS | SPI_2MHZ ;
REG_SPI_DATA = 0;
WAIT_FOR_NOT_BUSY();
// Return the result
result = ((result & 0x7F) << 5) | (REG_SPI_DATA >> 3);
REG_SPI_CR = 0;
return result ;
}
// Code from devkitpro/libnds/source/arm7/touch.c
//---------------------------------------------------------------------------------
signed int touch_read_value(int measure, int retry , int range) {
//---------------------------------------------------------------------------------
int i;
signed int this_value=0, this_range;
signed int last_value = touch_read(measure | 1);
for ( i=0; i < retry; i++) {
this_value = touch_read(measure | 1);
if ((last_value - this_value) > 0)
this_range = last_value - this_value;
else
this_range = this_value - last_value;
if (this_range <= range) break;
}
if ( i == range) this_value = 0;
return this_value;
}
unsigned char power_read(enum power_reg reg)
{
unsigned char val;
WAIT_FOR_NOT_BUSY();
REG_SPI_CR = SPI_ENABLE | SPI_CONTINUOUS | SPI_POWER | SPI_8CLOCKS | SPI_1MHZ ;
REG_SPI_DATA = POWER_READ | reg ;
WAIT_FOR_NOT_BUSY();
REG_SPI_CR = SPI_ENABLE | SPI_SINGLE | SPI_POWER | SPI_8CLOCKS | SPI_1MHZ ;
REG_SPI_DATA = 0x0;
WAIT_FOR_NOT_BUSY();
val = REG_SPI_DATA ;
REG_SPI_CR = 0 ;
return val;
}
void power_write( enum power_reg reg, unsigned char val )
{
WAIT_FOR_NOT_BUSY();
// Write the command and wait for it to complete
REG_SPI_CR = SPI_ENABLE | SPI_CONTINUOUS | SPI_POWER | SPI_8CLOCKS | SPI_1MHZ ;
REG_SPI_DATA = POWER_WRITE | reg ;
WAIT_FOR_NOT_BUSY();
// Write the data
REG_SPI_CR = SPI_ENABLE | SPI_SINGLE | SPI_POWER | SPI_8CLOCKS | SPI_1MHZ ;
REG_SPI_DATA = val;
REG_SPI_CR = 0 ;
}
void read_firmware(unsigned int address, unsigned char * destination, int count)
{
int i;
WAIT_FOR_NOT_BUSY();
REG_SPI_CR = SPI_ENABLE | SPI_CONTINUOUS | SPI_FIRMWARE | SPI_8CLOCKS | SPI_4MHZ ;
REG_SPI_DATA = 3;
WAIT_FOR_NOT_BUSY();
REG_SPI_DATA = (address >> 16) & 255;
WAIT_FOR_NOT_BUSY();
REG_SPI_DATA = (address >> 8) & 255;
WAIT_FOR_NOT_BUSY();
REG_SPI_DATA = (address) & 255;
WAIT_FOR_NOT_BUSY();
for (i = 0; i < count; i++) {
REG_SPI_DATA = 0;
WAIT_FOR_NOT_BUSY();
destination[i] = REG_SPI_DATA;
}
REG_SPI_CR = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -