📄 rs232.c
字号:
#include "dsp56f805_io.h"
#define RS_BUFFER_LNG 64
#define HALF_DUPLEX
/* done by Daniel Malik (daniel.malik@motorola.com) */
/* in case of HALF DUPLEX operation getchar() must be called periodically */
/* the portion needed to be called can be moved elsewhere (timer ISR etc) */
/* vesion 1.1 - internal variables changed to static */
static int rx_buffer[RS_BUFFER_LNG];
static int tx_buffer[RS_BUFFER_LNG];
static int *volatile tx_iptr,*volatile rx_iptr;
static int *tx_sptr,*rx_sptr; /* iptr belongs to ISR, sptr to SW */
asm void sci_tx_idle_isr(void) {
#ifdef HALF_DUPLEX
/* put your code to switch the half duplex */
/* line for reception here */
#endif
bfclr #0x0040,io.sci0.scicr /* disable this irq */
rti /* these two lines could be in the ifdef..endif as well, but just in case... */
}
asm void sci_tx_empty_isr(void) {
lea (sp)+
move r0,x:(sp)+
move y0,x:(sp)
move tx_sptr,y0
cmp tx_iptr,y0
beq ste1 /* no data available */
#ifdef HALF_DUPLEX
/* put your code to switch the half duplex */
/* line for transmission here */
bfset #0x0040,io.sci0.scicr /* enable tx_idle irq */
#endif
move tx_iptr,r0
move io.sci0.scisr,y0 /* read SR so irq flags are cleared */
move x:(r0)+,y0
move y0,io.sci0.scidr /* transmit data */
move r0,y0
cmp #tx_buffer+RS_BUFFER_LNG,y0
bne ste2
move #tx_buffer,r0
nop
ste2:
move r0,tx_iptr /* update pointer */
ste3:
pop y0
pop r0
rti
ste1:
bfclr #0x0080,io.sci0.scicr /* disable this interrupt */
bra ste3
}
asm void sci_rx_isr(void) {
lea (sp)+
move r0,x:(sp)+
move y0,x:(sp)
move io.sci0.scisr,y0 /* read SR so irq flag is cleared */
move rx_iptr,r0
move io.sci0.scidr,y0 /* read the data */
move y0,x:(r0)+
move r0,y0
cmp #rx_buffer+RS_BUFFER_LNG,y0
bne srx1
move #rx_buffer,r0
nop
srx1:
move r0,rx_iptr /* update pointer */
pop y0
pop r0
rti
}
char sci_getchar(void) {
int c;
#ifdef HALF_DUPLEX
if ((tx_iptr!=tx_sptr)&&(!(io.sci0.scisr&1))) io.sci0.scicr|=0x0080; /* enable tx_empty irq if no reception in progress */
/* previous line must be called periodically to enable tx_empty irq in case there is data to be sent */
#endif
if (rx_iptr==rx_sptr) return (-1); /* no data available */
c=*(rx_sptr++);
if (rx_sptr>=rx_buffer+RS_BUFFER_LNG) rx_sptr=rx_buffer;
return(c);
}
void sci_putchar(char character) {
int *newptr;
newptr=tx_sptr+1;
if (newptr>=(tx_buffer+RS_BUFFER_LNG)) newptr=tx_buffer;
while(newptr==tx_iptr) /* buffer is full, we have to wait */
if ((tx_iptr!=tx_sptr)&&(!(io.sci0.scisr&1))) io.sci0.scicr|=0x0080; /* enable tx_empty irq if no reception in progress */
*tx_sptr=character;
tx_sptr=newptr;
#ifdef HALF_DUPLEX
if (!(io.sci0.scisr&1)) io.sci0.scicr|=0x0080; /* enable tx_empty irq if no reception in progress */
#else if
sci0_scicr|=0x0080; /* enable tx_empty irq */
#endif
}
asm void sci_init_hw(int baud_div) {
move y0,io.sci0.scibr
move #0x002c,io.sci0.scicr /* enable Rx&Tx */
bfset #0x8000,cr.ipr /* enable level 1 interrupts */
bfset #0x0100,sr /* enable maskable interrupts */
bfclr #0x0200,sr
bfset #0x0010,io.ictn.gpr+13 /* assign IRQ 53 to group 1 */
bfset #0x1000,io.ictn.gpr+12 /* assign IRQ 51 to group 1 */
#ifdef HALF_DUPLEX
bfset #0x0100,io.ictn.gpr+12 /* assign IRQ 50 to group 1 */
#endif
rts
}
void sci_send_string(char *string) {
while (*string) sci_putchar(*(string++));
}
void sci_init(int baud_div) {
tx_iptr=tx_sptr=tx_buffer;
rx_iptr=rx_sptr=rx_buffer;
sci_init_hw(baud_div);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -