📄 spikbd.c
字号:
/************************
SPI0 Keyboard Test
************************/
// created, 2004.05.14, jylee
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "2413addr.h"
#include "console.h"
#include "spikbd.h"
#define ONEBIT 0x1
int putcToKBCTL(U8 c);
void getsFromKBCTL(U8 *m, int cnt);
unsigned int spikbd_rGPBCON,spikbd_rGPBDAT,spikbd_rGPBDN;
unsigned int spikbd_rGPDCON,spikbd_rGPDDAT,spikbd_rGPDDN;
unsigned int spikbd_rGPFCON,spikbd_rGPFDAT,spikbd_rGPFDN;
unsigned int spikbd_rGPGCON,spikbd_rGPGDAT,spikbd_rGPGDN;
/****************************************************************
* SMDK24xx SPI configuration *
* GPG3=nSS1, GPG5 =SPIMISO1, GPG6 =SPIMOSI1, GPG7 =SPICLK1 *
****************************************************************/
void * spikbd_func[][2]=
{
(void *)Test_Spikbd_IO, "SPI0 keybd IO test ",
(void *)Test_Spikbd_keyscan, "SPI0 keybd scan test ",
0,0
};
void SpiKbd_Test(void)
{
while(1)
{
int i = 0;
printf("\n");
while(1)
{ //display menu
printf("%2d:%s\n",i,spikbd_func[i][1]);
i++;
if((int)(spikbd_func[i][0])==0)
{
printf("\n");
break;
}
//if((i%3)==0)
//printf("\n");
}
printf("\nSelect the function to test : ");
i = GetIntNum();
printf("\n");
if(i==-1) break;
if(i>=0 && (i<(sizeof(spikbd_func)/8)) )
( (void (*)(void)) (spikbd_func[i][0]) )();
}
}
static void __irq Eint1(void)
{
U8 ui8ScanCode[4] = {0,};
static U32 isr_count = 0;
// jylee_20051117
// Be carefull, EINT[0..3] can be pending source on rEINTPEND SFR.
// So. You must clear a corresponding bit on rEINTPEND.
rEINTPEND = (1<<1);
ClearPending(BIT_EINT1);
getsFromKBCTL(ui8ScanCode, 1);
printf("keybd interrupt asserted -> scancode = 0x%x\n", ui8ScanCode[0]);
}
void SPIKBD_Port_Init()
{
spikbd_rGPBCON = rGPBCON;
spikbd_rGPBDAT = rGPBDAT;
spikbd_rGPBDN = rGPBDN;
spikbd_rGPDCON = rGPDCON;
spikbd_rGPDDAT = rGPDDAT;
spikbd_rGPDDN = rGPDDN;
spikbd_rGPFCON = rGPFCON;
spikbd_rGPFDAT = rGPFDAT;
spikbd_rGPFDN = rGPFDN;
spikbd_rGPGCON = rGPGCON;
spikbd_rGPGDAT = rGPGDAT;
spikbd_rGPGDN = rGPGDN;
// Setup IO port for SPI interface & Keyboard
// Setup EINT1 (KBDINT)
rGPFCON &= ~(0x3 << 2); // Clear GPF1
rGPFCON |= (0x2 << 2); // Set GPF1 to EINT1 for Keyboard interrupt
rGPFDN |= (1 << 1); // Set GPF1 Pull-Dn Disable
rEXTINT0 &= ~(0x7 << 4); // Clear EINT1
rEXTINT0 |= (0x2 << 4); // fallig edge triggered for EINT1
// setup SPI interface
// GPG5 : SPIMISO (KBDSPIMISO)
// GPG6 : SPIMOSI (KBDSPIMOSI)
// GPG7 : SPICLK (KBDSPICLK)
rGPGCON &= ~((0x3 << 10) | (0x3 << 12) | (0x3 << 14)); // Clear GPG5,6,7
rGPGCON |= ((0x3 << 10) | (0x3 << 12) | (0x3 << 14));
// setup _SS signal(nSS_KBD)
rGPBCON &= ~(0x3 << 12); // Clear GPB6
rGPBCON |= (ONEBIT << 12); // Set Port GPB6 to output for nSS signal
// setup _PWR_OK signal (KEYBOARD)
//rGPBCON &= ~(0x3 << 0); // Clear GPB0
//rGPBCON |= (ONEBIT << 0); // Set Port GPB0 to output for _PWR_OK signal
// 2413 KEYBOARD -> GPG13
// setup _PWR_OK signal (KEYBOARD)
rGPGCON &= ~(0x3 << 26); // Clear GPG13
rGPGCON |= (ONEBIT << 26); // Set Port GPG13 to output for _PWR_OK signal
rGPGDAT &=~(ONEBIT << 13); // set _PWR_OK to 0
}
void SPIKBD_Port_Return(void)
{
rGPBCON = spikbd_rGPBCON;
rGPBDAT = spikbd_rGPBDAT;
rGPBDN = spikbd_rGPBDN;
rGPDCON = spikbd_rGPDCON;
rGPDDAT = spikbd_rGPDDAT;
rGPDDN = spikbd_rGPDDN;
rGPFCON = spikbd_rGPFCON;
rGPFDAT = spikbd_rGPFDAT;
rGPFDN = spikbd_rGPFDN;
rGPGCON = spikbd_rGPGCON;
rGPGDAT = spikbd_rGPGDAT;
rGPGDN = spikbd_rGPGDN;
}
int putcToKBCTL(U8 c)
{
U32 i;
rGPBDAT &= ~(ONEBIT << 6); //Set _SS signal to low (Slave Select)
while((rSPSTA1 & (ONEBIT<<3))==0); // wait while busy
rSPTDAT1 = c; // write left justified data
while((rSPSTA1 & (ONEBIT<<3))==0); // wait while busy
rGPBDAT |= (ONEBIT << 6); //Set _SS signal to high (Slave Select)
i = rSPRDAT1;
// jylee_20051117
// S3C2413 case, SPI have 16 byte-depth FIFO
i = rSPRDAT1;
return(i);
}
void getsFromKBCTL(U8 *m, int cnt)
{
int i, j;
volatile tmp = 1;
for(j = 0; j < 3; j++)
tmp += tmp;
for(j = 0; j < 250 * 30; j++)
tmp += tmp;
for(i = 0; i < cnt; i++)
{
m[i] = putcToKBCTL(0xFF);
for(j = 0; j < 400; j++)
tmp+= tmp;
}
}
void putsToKBCTL(U8 *m, int cnt)
{
int i, j, x;
volatile tmp = 1;
for(j = 0; j < 3; j++)
x = j;
for(j = 0; j < 3; j++)
tmp += tmp;
for(j = 0; j < 250 * 30; j++)
tmp += tmp;
for(i = 0; i < cnt; i++) {
j = putcToKBCTL(m[i]);
for(j = 0; j < 400; j++)
tmp+= tmp;
for(j = 0; j < 400; j++)
x = j;
}
}
char lrc(U8 *buffer, int count)
{
char lrc;
int n;
lrc = buffer[0] ^ buffer[1];
for (n = 2; n < count; n++)
{
lrc ^= buffer[n];
}
if (lrc & 0x80)
lrc ^= 0xC0;
return lrc;
}
int USAR_WriteRegister(int reg, int data)
{
U8 cmd_buffer[4];
cmd_buffer[0] = 0x1b; //USAR_PH_WR;
cmd_buffer[1] = (unsigned char)reg;
cmd_buffer[2] = (unsigned char)data;
cmd_buffer[3] = lrc((U8 *)cmd_buffer,3);
putsToKBCTL((U8 *)cmd_buffer,4);
return TRUE;
}
void Kbd_PowerOn(void)
{
U8 msg[5];
int t;
char dummy = (char)0xff;
SPIKBD_Port_Init();
// Setup SPI registers
// Interrupt mode, prescaler enable, master mode, active high clock, format B, normal mode
rSPCON1 = (ONEBIT<<5)|(ONEBIT<<4)|(ONEBIT<<3)|(0x0<<2)|(ONEBIT<<1);
// Developer MUST change the value of prescaler properly whenever value of PCLK is changed.
rSPPRE1 = 255;// 99.121K = 203M/4/2/(255+1) PCLK=50.75Mhz FCLK=203Mhz SPICLK=99.121Khz
for(t=0;t<20000; t++); // delay
msg[0] = (char)0x1b; msg[1] = (char)0xa0; msg[2] = (char)0x7b; msg[3] = (char)0; // Initialize USAR
for(t=0; t < 10; t++) {
dummy = putcToKBCTL(0xff);
}
for(t=0; t<10; t++) { // wait for a while
putsToKBCTL(msg,3);
for(t=0;t<20000; t++);
}
t = 100;
while(t--) {
volatile U32 read_atn = 0;
rGPFCON &= ~(3<<2); // GPF1 defined as input port
read_atn = rGPFDAT & 0x2;
rGPFCON |= (2<<2); // GPF1 defined as interrupt port
if(read_atn == 0) { // Read _ATN (KBDINT) GPF1
break;
}
} //check _ATN
if(t != 0) {
getsFromKBCTL(msg,3);
}
t=100000;
while(t--); // delay
msg[0] = (char)0x1b; msg[1] = (char)0xa1; msg[2] = (char)0x7a; msg[3] = (char)0; //Initialization complete
putsToKBCTL(msg,3);
printf("KeybdPowerOn\n");
}
void Test_Spikbd_keyscan(void)
{
printf("[SPIKBD Test keyscan] start.\n");
Kbd_PowerOn();
rINTMSK |= BIT_EINT1;
rEXTINT0 = (rEXTINT0 & ~(7<<4)) | (2<<4); // falling edge
pISR_EINT1=(U32)Eint1;
rEINTPEND = (1<<1);
rSRCPND = BIT_EINT1;
rINTPND = BIT_EINT1;
rINTMSK=~(BIT_EINT1);
getchar();
rINTMSK = BIT_ALLMSK;
printf("[SPIKBD Test keyscan] end.\n");
SPIKBD_Port_Return();
}
void SPIKBD_Port_Init_IO()
{
spikbd_rGPBCON = rGPBCON;
spikbd_rGPBDAT = rGPBDAT;
spikbd_rGPBDN = rGPBDN;
spikbd_rGPDCON = rGPDCON;
spikbd_rGPDDAT = rGPDDAT;
spikbd_rGPDDN = rGPDDN;
spikbd_rGPFCON = rGPFCON;
spikbd_rGPFDAT = rGPFDAT;
spikbd_rGPFDN = rGPFDN;
spikbd_rGPGCON = rGPGCON;
spikbd_rGPGDAT = rGPGDAT;
spikbd_rGPGDN = rGPGDN;
// Setup IO port for SPI interface & Keyboard
// Setup KBDINT as output
rGPFCON &= ~(0x3 << 2); // Clear GPF1
rGPFCON |= (0x1 << 2); // Set GPF1 to EINT1 for Keyboard interrupt
// setup SPI interface
// GPG5 : SPIMISO (KBDSPIMISO)
// GPG6 : SPIMOSI (KBDSPIMOSI)
// GPG7 : SPICLK (KBDSPICLK)
rGPGCON &= ~((0x3 << 10) | (0x3 << 12) | (0x3 << 14)); // Clear GPG5,6,7
rGPGCON |= ((0x1 << 10) | (0x1 << 12) | (0x1 << 14));
// setup _SS signal(nSS_KBD)
rGPBCON &= ~(0x3 << 12); // Clear GPB6
rGPBCON |= (ONEBIT << 12); // Set Port GPB6 to output for nSS signal
// setup _PWR_OK signal (KEYBOARD)
// rGPBCON &= ~(0x3 << 0); // Clear GPB0
// rGPBCON |= (ONEBIT << 0); // Set Port GPB0 to output for _PWR_OK signal
// 2413 case KEYBOARD -> GPG13
// setup _PWR_OK signal (KEYBOARD) ->
rGPGCON &= ~(0x3 << 26); // Clear GPG13
rGPGCON |= (ONEBIT << 26); // Set Port GPG13 to output for _PWR_OK signal
}
void Test_Spikbd_IO(void)
{
int i, j;
printf("[SPIKBD IO-Test] start\n");
SPIKBD_Port_Init_IO();
do
{
printf("test loop going - %d\n", i);
i++;
if (i%2)
{
rGPFDAT &= ~(1<<1); // GPF1 KBDINT
rGPBDAT &= ~(1<<6); // GPB6
//rGPBDAT &= ~(1<<0); // GPB0
rGPGDAT &= ~(1<<13); // GPG13
rGPGDAT &= ~(7<<5); // GPG5,6,7 (SPIMISO,SPIMOSI,SPICLK)
}
else
{
rGPFDAT |= (1<<1); // GPF1 KBDINT
rGPBDAT |= (1<<6); // GPB6
//rGPBDAT |= (1<<0); // GPB0
rGPGDAT |= (1<<13); // GPG13
rGPGDAT |= (7<<5); // GPG5,6,7 (SPIMISO,SPIMOSI,SPICLK)
}
} while(Uart_GetKey() == 0);
printf("[SPIKBD IO-Test] end\n");
SPIKBD_Port_Return();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -