diff options
author | Karl Kurbjun <kkurbjun@gmail.com> | 2009-04-14 05:17:03 +0000 |
---|---|---|
committer | Karl Kurbjun <kkurbjun@gmail.com> | 2009-04-14 05:17:03 +0000 |
commit | 5b6af5e56019eec701f81450b79ca413fbae6032 (patch) | |
tree | 6a901be8a525c7099ab55e0c726fe8f0bf31360e /firmware/target | |
parent | 140c7e6f663d57f4ceae51063932bcbfe3bc0165 (diff) |
M:Robe 500 Fix a bug in the UART receive buffer - remote does not appear to stop working anymore, add support for interupt driven transmit, add very rough remote LCD support.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20706 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/tms320dm320/mrobe-500/button-mr500.c | 40 | ||||
-rw-r--r-- | firmware/target/arm/tms320dm320/mrobe-500/lcd-remote-mr500.c | 204 | ||||
-rw-r--r-- | firmware/target/arm/tms320dm320/uart-dm320.c | 121 | ||||
-rw-r--r-- | firmware/target/arm/tms320dm320/uart-target.h | 6 |
4 files changed, 207 insertions, 164 deletions
diff --git a/firmware/target/arm/tms320dm320/mrobe-500/button-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/button-mr500.c index bc163b1070..00096ce2ad 100644 --- a/firmware/target/arm/tms320dm320/mrobe-500/button-mr500.c +++ b/firmware/target/arm/tms320dm320/mrobe-500/button-mr500.c @@ -186,27 +186,26 @@ int button_read_device(int *data) } retval=uart1_gets_queue(r_buffer, 5); - do + + for(calbuf=0;calbuf<4;calbuf++) { - for(calbuf=0;calbuf<4;calbuf++) - { - if((r_buffer[calbuf]&0xF0)==0xF0 && (r_buffer[calbuf+1]&0xF0)!=0xF0) - break; - } - calbuf++; - if(calbuf==5) - calbuf=0; - if(retval>=0) - { - r_button |= r_buffer[calbuf]; - oldbutton=r_button; - } - else - { - r_button=oldbutton; - } - } while((retval=uart1_gets_queue(r_buffer, 5))>=5); - + if((r_buffer[calbuf]&0xF0)==0xF0 && (r_buffer[calbuf+1]&0xF0)!=0xF0) + break; + } + calbuf++; + if(calbuf==5) + calbuf=0; + if(retval>=0) + { + uart1_clear_queue(); + r_button |= r_buffer[calbuf]; + oldbutton=r_button; + } + else + { + r_button=oldbutton; + } + return r_button; } @@ -226,6 +225,5 @@ void GIO14(void) read_battery_inputs(); break; } - //touch_available = true; IO_INTC_IRQ2 = (1<<3); /* IRQ_GIO14 == 35 */ } diff --git a/firmware/target/arm/tms320dm320/mrobe-500/lcd-remote-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/lcd-remote-mr500.c index 5cdc00ce6a..0a41b2241f 100644 --- a/firmware/target/arm/tms320dm320/mrobe-500/lcd-remote-mr500.c +++ b/firmware/target/arm/tms320dm320/mrobe-500/lcd-remote-mr500.c @@ -33,17 +33,22 @@ static enum remote_control_states REMOTE_CONTROL_NOP, REMOTE_CONTROL_POWER, REMOTE_CONTROL_MASK, - REMOTE_CONTROL_DRAW1, - REMOTE_CONTROL_DRAW_PAUSE1, - REMOTE_CONTROL_DRAW2, - REMOTE_CONTROL_DRAW_PAUSE2, + REMOTE_CONTROL_DRAW, REMOTE_CONTROL_SLEEP -} remote_state_control = REMOTE_CONTROL_NOP; +} remote_state_control = REMOTE_CONTROL_NOP, remote_state_control_next; + +static enum remote_draw_states +{ + DRAW_TOP, + DRAW_BOTTOM, + DRAW_PAUSE, +} remote_state_draw = DRAW_TOP, remote_state_draw_next; bool remote_initialized=true; unsigned char remote_contrast=DEFAULT_REMOTE_CONTRAST_SETTING; unsigned char remote_power=0x00; +unsigned char remote_mask=0x00; /*** hardware configuration ***/ @@ -54,7 +59,7 @@ int lcd_remote_default_contrast(void) void lcd_remote_sleep(void) { - remote_state_control=REMOTE_CONTROL_SLEEP; + remote_state_control_next=REMOTE_CONTROL_SLEEP; } void lcd_remote_powersave(bool on) @@ -62,19 +67,19 @@ void lcd_remote_powersave(bool on) if(on) { remote_power|=0xC0; - remote_state_control=REMOTE_CONTROL_POWER; + remote_state_control_next=REMOTE_CONTROL_POWER; } else { remote_power&=~(0xC0); - remote_state_control=REMOTE_CONTROL_POWER; + remote_state_control_next=REMOTE_CONTROL_POWER; } } void lcd_remote_set_contrast(int val) { remote_contrast=(char)val; - remote_state_control=REMOTE_CONTROL_POWER; + remote_state_control_next=REMOTE_CONTROL_POWER; } void lcd_remote_set_invert_display(bool yesno) @@ -82,12 +87,6 @@ void lcd_remote_set_invert_display(bool yesno) (void)yesno; } -/* turn the display upside down (call lcd_remote_update() afterwards) */ -void lcd_remote_set_flip(bool yesno) -{ - (void)yesno; -} - bool remote_detect(void) { return true; @@ -96,32 +95,41 @@ bool remote_detect(void) void lcd_remote_on(void) { remote_power|=0x80; - remote_state_control=REMOTE_CONTROL_POWER; + remote_state_control_next=REMOTE_CONTROL_POWER; } void lcd_remote_off(void) { remote_power&=~(0x80); - remote_state_control=REMOTE_CONTROL_POWER; + remote_state_control_next=REMOTE_CONTROL_POWER; } -unsigned char lcd_remote_test[16]= - {0x80,0xFF,0x80,0x00,0xFF,0x89,0x89,0x00,0xC1,0x89,0x8F,0x80,0xFF,0x80,0,0}; +/* This is the maximum transfer size to the remote (op 0x51= 7 bytes setup+79 + * bytes screen data+xor+sum + */ +unsigned char remote_payload[88]; +unsigned char remote_payload_size; +bool remote_repeat_draw=false; + +unsigned char remote_draw_x, remote_draw_y, + remote_draw_width, remote_draw_height; /* Monitor remote hotswap */ static void remote_tick(void) { unsigned char i; - unsigned char remote_payload[10], remote_payload_size; - unsigned char remote_check_xor, remote_check_sum; + static unsigned char pause_length=0; + + if(remote_state_control!=REMOTE_CONTROL_DRAW) + remote_state_control=remote_state_control_next; switch (remote_state_control) { case REMOTE_CONTROL_IDLE: - remote_payload_size=0; remote_state_control=REMOTE_CONTROL_IDLE; break; + case REMOTE_CONTROL_NOP: remote_payload[0]=0x11; remote_payload[1]=0x30; @@ -129,6 +137,7 @@ static void remote_tick(void) remote_payload_size=2; remote_state_control=REMOTE_CONTROL_NOP; break; + case REMOTE_CONTROL_POWER: remote_payload[0]=0x31; remote_payload[1]=remote_power; @@ -137,51 +146,65 @@ static void remote_tick(void) remote_payload_size=3; remote_state_control=REMOTE_CONTROL_NOP; break; + case REMOTE_CONTROL_MASK: remote_payload[0]=0x41; - remote_payload[1]=0x94; + remote_payload[1]=remote_mask; remote_payload_size=2; remote_state_control=REMOTE_CONTROL_NOP; break; - case REMOTE_CONTROL_DRAW1: - remote_payload[0]=0x51; - remote_payload[1]=0x80; - remote_payload[2]=14; - remote_payload[3]=0; - remote_payload[4]=0; - remote_payload[5]=14; - remote_payload[6]=8; - - remote_payload_size=7; - remote_state_control=REMOTE_CONTROL_DRAW_PAUSE1; - break; - case REMOTE_CONTROL_DRAW_PAUSE1: - remote_payload[0]=0x11; - remote_payload[1]=0x30; - remote_payload_size=2; - remote_state_control=REMOTE_CONTROL_DRAW2; - break; - case REMOTE_CONTROL_DRAW2: + case REMOTE_CONTROL_DRAW: remote_payload[0]=0x51; remote_payload[1]=0x80; - remote_payload[2]=14; - remote_payload[3]=0; - remote_payload[4]=8; - remote_payload[5]=14; - remote_payload[6]=16; + remote_payload[2]=remote_draw_width; + remote_payload[3]=remote_draw_x; - remote_payload_size=7; - remote_state_control=REMOTE_CONTROL_DRAW_PAUSE2; - break; - case REMOTE_CONTROL_DRAW_PAUSE2: - remote_payload[0]=0x11; - remote_payload[1]=0x30; + remote_payload[5]=remote_draw_x+remote_draw_width; + remote_payload_size=7+remote_payload[2]; - remote_payload_size=2; - remote_state_control=REMOTE_CONTROL_NOP; + switch (remote_state_draw) + { + case DRAW_TOP: + remote_payload[4]=0; + remote_payload[6]=8; + + pause_length=6; + remote_state_draw_next=DRAW_BOTTOM; + remote_state_draw=DRAW_PAUSE; + break; + + case DRAW_BOTTOM: + remote_payload[4]=8; + remote_payload[6]=16; + + pause_length=6; + remote_state_draw_next=DRAW_TOP; + remote_state_draw=DRAW_PAUSE; + break; + + case DRAW_PAUSE: + remote_payload_size=0; + + if(--pause_length==0) + { + if(remote_state_draw_next==DRAW_TOP) + remote_state_control=REMOTE_CONTROL_NOP; + + remote_state_draw=remote_state_draw_next; + } + else + remote_state_draw=DRAW_PAUSE; + + break; + + default: + remote_payload_size=0; + break; + } break; + case REMOTE_CONTROL_SLEEP: remote_payload[0]=0x71; remote_payload[1]=0x30; @@ -189,6 +212,7 @@ static void remote_tick(void) remote_payload_size=2; remote_state_control=REMOTE_CONTROL_IDLE; break; + default: remote_payload_size=0; break; @@ -199,46 +223,25 @@ static void remote_tick(void) return; } - remote_check_xor=remote_payload[0]; - remote_check_sum=remote_payload[0]; - for(i=1; i<remote_payload_size; i++) - { - remote_check_xor^=remote_payload[i]; - remote_check_sum+=remote_payload[i]; - } - if(remote_payload[0]==0x51) { - unsigned char offset; - unsigned char x; - - if(remote_payload[4]==8) - { - offset=79; - } - else - { - offset=0; - } - - for (x = 0; x < 14; x++) + for(i=7; i<remote_payload_size; i++) { - remote_check_xor^=lcd_remote_test[x]; - remote_check_sum+=lcd_remote_test[x]; + remote_payload[i]= + lcd_remote_framebuffer[remote_payload[4]>>3][i+remote_draw_x-7]; } - - uart1_puts(remote_payload, remote_payload_size); - lcd_remote_test[14]=remote_check_xor; - lcd_remote_test[15]=remote_check_sum; - uart1_puts(lcd_remote_test, 16); } - else - { - remote_payload[remote_payload_size]=remote_check_xor; - remote_payload[remote_payload_size+1]=remote_check_sum; - uart1_puts(remote_payload, remote_payload_size+2); + /* Calculate the xor and sum to place in the payload */ + remote_payload[remote_payload_size]=remote_payload[0]; + remote_payload[remote_payload_size+1]=remote_payload[0]; + for(i=1; i<remote_payload_size; i++) + { + remote_payload[remote_payload_size]^=remote_payload[i]; + remote_payload[remote_payload_size+1]+=remote_payload[i]; } + + uart1_puts(remote_payload, remote_payload_size+2); } void lcd_remote_init_device(void) @@ -247,6 +250,8 @@ void lcd_remote_init_device(void) if (remote_detect()) lcd_remote_on(); + lcd_remote_update(); + /* put the remote control in the tick task */ tick_add_task(remote_tick); } @@ -255,33 +260,28 @@ void lcd_remote_init_device(void) This must be called after all other LCD functions that change the display. */ void lcd_remote_update(void) { - if(remote_state_control!=REMOTE_CONTROL_DRAW1 - && remote_state_control!=REMOTE_CONTROL_DRAW_PAUSE1 - && remote_state_control!=REMOTE_CONTROL_DRAW2 - && remote_state_control!=REMOTE_CONTROL_DRAW_PAUSE2) - { - remote_state_control=REMOTE_CONTROL_DRAW1; - } + lcd_remote_update_rect(0, 0, LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT); } /* Update a fraction of the display. */ void lcd_remote_update_rect(int x, int y, int width, int height) { - (void)x; - (void)y; - (void)width; - (void)height; - lcd_remote_update(); + remote_draw_x=x; + remote_draw_y=y; + remote_draw_width=width; + remote_draw_height=height; + + remote_state_control=REMOTE_CONTROL_DRAW; } void _remote_backlight_on(void) { remote_power|=0x40; - remote_state_control=REMOTE_CONTROL_POWER; + remote_state_control_next=REMOTE_CONTROL_POWER; } void _remote_backlight_off(void) { remote_power&=~(0x40); - remote_state_control=REMOTE_CONTROL_POWER; + remote_state_control_next=REMOTE_CONTROL_POWER; } diff --git a/firmware/target/arm/tms320dm320/uart-dm320.c b/firmware/target/arm/tms320dm320/uart-dm320.c index 5e2ad5e2be..d68beb6e01 100644 --- a/firmware/target/arm/tms320dm320/uart-dm320.c +++ b/firmware/target/arm/tms320dm320/uart-dm320.c @@ -27,37 +27,48 @@ #define MAX_UART_BUFFER 31 #define SEND_RING_SIZE 256 -#define RECIEVE_RING_SIZE 20 +#define RECEIVE_RING_SIZE 20 char -// uart1_send_buffer_ring[SEND_RING_SIZE], - uart1_recieve_buffer_ring[RECIEVE_RING_SIZE]; + uart1_send_buffer_ring[SEND_RING_SIZE], + uart1_receive_buffer_ring[RECEIVE_RING_SIZE]; -//static unsigned int uart1_send_count, uart1_send_read, uart1_send_write; -static unsigned int uart1_recieve_count, uart1_recieve_read, uart1_recieve_write; +static volatile int uart1_send_count, uart1_send_read, uart1_send_write; +static volatile int uart1_receive_count, uart1_receive_read, uart1_receive_write; void uart_init(void) { // 8-N-1 - IO_UART1_MSR = 0x8000; + IO_UART1_MSR = 0xC400; IO_UART1_BRSR = 0x0057; - IO_UART1_RFCR = 0x8010; /* Trigger later */ + IO_UART1_RFCR = 0x8020; /* Trigger later */ + IO_UART1_TFCR = 0x0000; /* Trigger level */ /* gio 27 is input, uart1 rx gio 28 is output, uart1 tx */ IO_GIO_DIR1 |= (1<<11); /* gio 27 */ IO_GIO_DIR1 &= ~(1<<12); /* gio 28 */ - /* init the recieve buffer */ - uart1_recieve_count=0; - uart1_recieve_read=0; - uart1_recieve_write=0; + /* init the receive buffer */ + uart1_receive_count=0; + uart1_receive_read=0; + uart1_receive_write=0; + + /* init the send buffer */ + uart1_send_count=0; + uart1_send_read=0; + uart1_send_write=0; /* Enable the interrupt */ IO_INTC_EINT0 |= INTR_EINT0_UART1; } + +/* This function is not interrupt driven */ void uart1_putc(char ch) { + /* Wait for the interupt driven puts to finish */ + while(uart1_send_count>0); + /* Wait for room in FIFO */ while ((IO_UART1_TFCR & 0x3f) >= 0x20); @@ -67,45 +78,73 @@ void uart1_putc(char ch) void uart1_puts(const char *str, int size) { - int count=0; - while (count<size) + if(size>SEND_RING_SIZE) + panicf("Too much data passed to uart1_puts"); + + /* Wait for the previous transfer to finish */ + while(uart1_send_count>0); + + memcpy(uart1_send_buffer_ring, str, size); + + /* Disable interrupt while modifying the pointers */ + IO_INTC_EINT0 &= ~INTR_EINT0_UART1; + + uart1_send_count=size; + uart1_send_read=0; + + /* prime the hardware buffer */ + while(((IO_UART1_TFCR & 0x3f) < 0x20) && (uart1_send_count > 0)) { - uart1_putc(str[count]); - count++; + IO_UART1_DTRR=uart1_send_buffer_ring[uart1_send_read++]; + uart1_send_count--; } + + /* Enable interrupt */ + IO_INTC_EINT0 |= INTR_EINT0_UART1; +} + +void uart1_clear_queue(void) +{ + /* Disable interrupt while modifying the pointers */ + IO_INTC_EINT0 &= ~INTR_EINT0_UART1; + uart1_receive_write=0; + uart1_receive_count=0; + uart1_receive_read=0; + /* Enable interrupt */ + IO_INTC_EINT0 |= INTR_EINT0_UART1; } /* This function returns the number of bytes left in the queue after a read is done (negative if fail)*/ -int uart1_gets_queue(char *str, unsigned int size) +int uart1_gets_queue(char *str, int size) { + /* Disable the interrupt while modifying the pointers */ IO_INTC_EINT0 &= ~INTR_EINT0_UART1; int retval; - if(uart1_recieve_count<size) + if(uart1_receive_count<size) { retval= -1; } else { - if(uart1_recieve_read+size<RECIEVE_RING_SIZE) + if(uart1_receive_read+size<=RECEIVE_RING_SIZE) { - memcpy(str,uart1_recieve_buffer_ring+uart1_recieve_read,size); + memcpy(str,uart1_receive_buffer_ring+uart1_receive_read,size); + + uart1_receive_read+=size; } else { - int tempcount=(RECIEVE_RING_SIZE-uart1_recieve_read); - memcpy(str,uart1_recieve_buffer_ring+uart1_recieve_read,tempcount); - memcpy(str+tempcount,uart1_recieve_buffer_ring,size-tempcount); + int tempcount=(RECEIVE_RING_SIZE-uart1_receive_read); + memcpy(str,uart1_receive_buffer_ring+uart1_receive_read,tempcount); + memcpy(str+tempcount,uart1_receive_buffer_ring,size-tempcount); + + uart1_receive_read=size-tempcount; } - uart1_recieve_count-=size; - - if(uart1_recieve_read+size<RECIEVE_RING_SIZE) - uart1_recieve_read+=size; - else - uart1_recieve_read=size-(RECIEVE_RING_SIZE-uart1_recieve_read); - - retval=uart1_recieve_count; + uart1_receive_count-=size; + + retval=uart1_receive_count; } /* Enable the interrupt */ @@ -114,23 +153,29 @@ int uart1_gets_queue(char *str, unsigned int size) return retval; } -/* UART1 receive interupt handler */ +/* UART1 receive/transmit interupt handler */ void UART1(void) { while (IO_UART1_RFCR & 0x3f) { - if (uart1_recieve_count > RECIEVE_RING_SIZE) - panicf("UART1 buffer overflow"); + if (uart1_receive_count > RECEIVE_RING_SIZE) + panicf("UART1 receive buffer overflow"); else { - if(uart1_recieve_write>=RECIEVE_RING_SIZE) - uart1_recieve_write=0; + if(uart1_receive_write>=RECEIVE_RING_SIZE) + uart1_receive_write=0; - uart1_recieve_buffer_ring[uart1_recieve_write] = IO_UART1_DTRR & 0xff; - uart1_recieve_write++; - uart1_recieve_count++; + uart1_receive_buffer_ring[uart1_receive_write]=IO_UART1_DTRR & 0xff; + uart1_receive_write++; + uart1_receive_count++; } } + while ( ((IO_UART1_TFCR & 0x3f) < 0x20) && (uart1_send_count > 0) ) + { + IO_UART1_DTRR=uart1_send_buffer_ring[uart1_send_read++]; + uart1_send_count--; + } + IO_INTC_IRQ0 = INTR_IRQ0_UART1; } diff --git a/firmware/target/arm/tms320dm320/uart-target.h b/firmware/target/arm/tms320dm320/uart-target.h index 68145b8358..9be9ba51fe 100644 --- a/firmware/target/arm/tms320dm320/uart-target.h +++ b/firmware/target/arm/tms320dm320/uart-target.h @@ -23,10 +23,10 @@ void uart_init(void);
bool uart1_available(void);
-int uart1_gets_queue(char *, unsigned int);
+int uart1_gets_queue(char *, int);
void uart1_puts(const char *str, int size);
-void uart1_gets(char *str, unsigned int size);
+void uart1_gets(char *str, int size);
void uart1_putc(char ch);
-
+void uart1_clear_queue(void);
#endif
|