?? msp430-fw-interrupts.c
字號:
inBit = P2IN & BIT1;
if(inBit!=0 && wheel_counter<32000)
{ wheel_counter += 1; }
else if(inBit==0 && wheel_counter>-32000)
{ wheel_counter -= 1; }
// reset interrupt flag
P2IFG &= ~BIT0;
}
if ((P2IFG&KBD_CLK)!=0) {
// -- AT keyboard
// keyboard serial stream:
// falling clock edge data in
// start bit 0, 8 bit LSB ... MSB, odd parity, stop bit 1
//
// from scope traces and
// http://www.beyondlogic.org/keyboard/keybrd.htm
//
// (A) B C D E
// ----+ +------+ +------+
// CLK | <int | | | | 5..25 kHz
// +-------+ +------+ +-----...
//
// -+ DATA +----------+
// | 0 | 1 | 0
// +---------+ +---------------...
// timeout loop: xtal 4MHz/16000=250 Hz (plenty for 5..25kHz AT kbd clock)
#ifdef NEW_KBD_FUNCS
if(risingedge==1) {
// trigged on rising edge (data done), switch back to falling edge trig
P2IES |= KBD_CLK;
risingedge=0;
} else {
// trigged on falling edge (data in), change to rising edge trig
P2IES &= ~KBD_CLK;
risingedge=1;
// read the bit
inBit = P2IN & KBD_DAT;
intPort2_kbdRetry:
// start of new sequence?
if(kbdBitcount==0) {
// start bit 0
if(inBit==0) {
++kbdBitcount;
kbdData=0;
} else {
// out of sync, wait for next bit
P6OUT |= LED_1;
}
// continue current sequence: databits, parity, stopbit
} else {
// if previous bit over 3 ticks ago, reset sequence
if((sys_ticks-old_sys_ticks)>20) {
kbdBitcount=0;
kbdData=0;
// P6OUT ^= LED_1; // toggle diagnostic LED
goto intPort2_kbdRetry; // reinterpret as start bit
}
// data bits
if(kbdBitcount<=(1+8)) {
// LSB comes first, so shift bits in from left side
kbdData /= 2;
if(inBit!=0)
{ kbdData |= 0x80; }
++kbdBitcount;
// parity - ignored
} else if (kbdBitcount==(1+8+1)) {
++kbdBitcount;
// stop bit 1
} else {
if(inBit==0) {
// out of sync
P6OUT ^= LED_1; // toggle diagnostic LED
FWConfig.KBD_failure = 1;
} else {
if(!(kbdUnreadCount>=(KBD_BUFSIZE-1)))
{ kbdUnreadCount++; }
kbdBufPos=(kbdBufPos+1)%KBD_BUFSIZE;
kbdBuf[kbdBufPos] = kbdData;
P6OUT &= ~LED_1;
}
kbdBitcount = 0;
}
}
}
old_sys_ticks = sys_ticks;
#else
// check start bit 0, cont B (wait for rising edge)
if((P2IN&KBD_DAT)!=0) fail=1;
timeout=0;
while((P2IN&KBD_CLK)==0 && (timeout++)<KBD_DLY && fail==0) { _NOP(); }
if(timeout>KBD_DLY-1) fail=1;
// cont C, wait for falling edges, read in 8 bits
for(i=0;i<8 && fail==0;++i) { // &&fail==0
// falling edge
timeout=0;
while((P2IN&KBD_CLK)!=0 && (timeout++)<KBD_DLY) { _NOP(); }
if(timeout>KBD_DLY-1) fail=1;
// data, LSB first MSB last
kbdChar /= 2;
if((P2IN&KBD_DAT)!=0) kbdChar+=0x80;
// rising edge
timeout=0; while((P2IN&KBD_CLK)==0 && (timeout++)<KBD_DLY && fail==0) _NOP(); if(timeout>KBD_DLY-1) fail=1;
}
// skip parity bit, falling + rising edge
timeout=0; while((P2IN&KBD_CLK)!=0 && (timeout++)<KBD_DLY && fail==0) _NOP(); if(timeout>KBD_DLY-1) fail=1;
timeout=0; while((P2IN&KBD_CLK)==0 && (timeout++)<KBD_DLY && fail==0) _NOP(); if(timeout>KBD_DLY-1) fail=1;
// check stop bit 1, falling + rising edge
timeout=0; while((P2IN&KBD_CLK)!=0 && (timeout++)<KBD_DLY && fail==0) _NOP(); if(timeout>KBD_DLY-1) fail=1;
if((P2IN&KBD_DAT)==0) fail=1;
timeout=0; while((P2IN&KBD_CLK)==0 && (timeout++)<KBD_DLY && fail==0) _NOP(); // last rising edge
if(fail==0) {
if(!(kbdUnreadCount>=(KBD_BUFSIZE-1)))
{ kbdUnreadCount++; }
kbdBufPos=(kbdBufPos+1)%KBD_BUFSIZE;
kbdBuf[kbdBufPos] = kbdChar;
} else {
// P6OUT |= LED_1; // kbd error led on
FWConfig.KBD_failure = 1;
}
#endif
// reset interrupt flag
P2IFG &= ~KBD_CLK;
}
}
//===================================================================
//
// KEYBOARD HELPER FUNCTIONS
//
//-------------------------------------------------------------------
// kdbSuspend ( )
// Tell the AT keyboard to momentarily pause sending of any data.
//
void kbdSuspend(void)
{
/*
_DINT();
P2IES &= ~KBD_CLK; // int off
P2DIR |= KBD_CLK; // clock line as output
P2OUT &= ~KBD_CLK; // set line low = keyboard doesn't transmit
P2IFG &= ~KBD_CLK; // clear int flag
_EINT();
*/
return;
}
//-------------------------------------------------------------------
// kbdResume ( )
// Allow the AT keyboard to send data. If the keyboard was previously
// suspended and new button press data accumulated in the keyboards
// own memory buffer, it will start sending that data soon.
//
void kbdResume(void)
{
/*
_DINT();
P2DIR &= ~KBD_CLK; // clock line as input
P2IES |= KBD_CLK; // int on
P2IFG &= ~KBD_CLK; // clear int flag
_EINT();
*/
return;
}
//-------------------------------------------------------------------
// unsigned char kbdGetChar ( )
// Returns the next character from our keyboard buffer, or 0 if
// the buffer was empty.
//
unsigned char kbdGetChar(void)
{
unsigned char tmp;
if(kbdUnreadCount<=0) return '\0';
_DINT();
if(kbdBufPos>KBD_BUFSIZE)
{ kbdBufPos = 0; kbdUnreadCount=1; }
kbdUnreadCount--;
tmp = (kbdBufPos-kbdUnreadCount)%KBD_BUFSIZE;
tmp = kbdBuf[tmp];
_EINT();
return tmp;
}
//===================================================================
//
// PC SERIAL COMM HELPER FUNCTIONS
//
//-------------------------------------------------------------------
// PC_writeChar ( unsigned char )
// Queue a new data byte to transmit to the PC.
//
void PC_writeChar(unsigned char out)
{
// currently not sending?
if(pcTxDone==1) {
// just place the new char into the hardware buffer
TXBUF1 = out; pcTxUnsentCount=0;
pcTxDone = 0;
return;
}
// already sending, add to software buffer for sending later
while(pcTxUnsentCount>=PC_TXBUF) // buffer overflow
{ _NOP(); } // wait for tx interrupt driver to 'free' 1 byte
_DINT();
++pcTxBufPos; // append byte to the buffer
pcTxBufPos%=PC_TXBUF;
pcTxUnsentCount++;
pcTxBuf[pcTxBufPos] = out;
_EINT();
return;
}
//-------------------------------------------------------------------
// PC_writeString ( char * )
// Write a null-terminated string to the serial port
//
void PC_writeString(char *str)
{
int i;
for(i=0;i<100 && *(str+i)!='\0';i++)
{ PC_writeChar(*(str+i)); }
return;
}
//-------------------------------------------------------------------
// PC_writeLine ( char * )
// Write a null-terminated string to the serial port.
// Precedes the string with a # and adds a newline.
//
void PC_writeLine(char *str)
{
PC_writeString("# ");
PC_writeString(str);
PC_writeString((char*)STR_CRLF);
}
//-------------------------------------------------------------------
// unsigned char PC_readChar ( )
// Returns the next character from our serial input buffer, or 0 if
// the buffer was empty.
//
unsigned char PC_readChar(void)
{
unsigned char tmp;
if(pcRxUnreadCount<1) { return 0; }
_DINT();
if(pcRxBufPos>PC_RXBUF) {
pcRxBufPos = 0;
pcRxUnreadCount = 1;
}
do {
tmp = pcRxBuf[pcRxBufPos];
--pcRxBufPos;
pcRxBufPos%=PC_RXBUF;
pcRxUnreadCount--;
} while((tmp==0) && (pcRxUnreadCount>0));
_EINT();
return tmp;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -