--- save/jw002.asm 2004-04-14 14:59:37.000000000 -0700 +++ jw002.asm 2004-04-14 19:09:57.000000000 -0700 @@ -116,6 +116,7 @@ .equ hscroll_fill_en, 14 .equ hscroll_redraw, 15 .equ turn_lcd_on, 16 + .equ clocked_serial_mode, 17 ; indicates clocked serial mode ;external data memory .equ rx_buf_page, 0 ;256 byte rx buffer, 0000 to 00FF @@ -154,7 +155,18 @@ .equ bank_pin1, 0x95 ;ROM memory bank selects .equ bank_pin2, 0x96 - + ; internal memory for clocked serial mode + ; NB: these overlay internal memory used for push buttons + ; which are not supported in clocked serial mode + .equ serial_bit_cnt, pb_scan_state + .equ serial_acc, pb_state + + ; port pins for clocked serial mode (these overload the pins used for pushbuttons) + .equ clk_ser_req, 0x90 ;p1.0 - hold low during startup + .equ serial_data, 0x92 ;p1.2 - incoming data + .equ serial_clk, 0xB2 ;p3.2 - bit clock (negative edge) + .equ serial_data_rx, 0xB3 ;p3.3 - acknowledge + ;pushbutton config ; ; autorepeat delay: no autorepeat, 400 ms, 650 ms, 900 ms @@ -173,6 +185,9 @@ .org location ljmp begin + .org location+3 + ljmp extern0_isr + .org location+11 ljmp timer0_isr @@ -236,6 +251,7 @@ clr ignore_input_mode clr hscroll_fill_en clr hscroll_redraw + clr clocked_serial_mode mov hscroll_fill_row, #0 mov hscroll_en, #0 mov hscroll_font0, #0 @@ -1945,7 +1961,7 @@ setb pb_recv_2 setb pb_recv_3 setb pb_recv_4 - clr pb_xmit_1 + setb pb_xmit_1 setb pb_xmit_2 setb pb_xmit_3 mov pb_scan_state, #0 @@ -1980,14 +1996,93 @@ mov pb_config+9, a mov pb_config+10, a mov pb_config+11, a + +; check for clocked serial mode request + jnb clk_ser_req, activate_clocked_serial_mode + +; normal asynchronous mode + clr pb_xmit_1 clr pt0 + sjmp finish_timer0_setup + +; prepare for clocked serial mode +activate_clocked_serial_mode: + setb clocked_serial_mode + mov serial_bit_cnt, #8 + setb it0 ; set for interrupt on falling edge of p3.2 + setb ex0 + setb px0 + +finish_timer0_setup: setb et0 setb ea setb tr0 lcall copy_strings_to_sram ret +;-------------------------------------------------------------------- +; This ISR will be called when a falling edge is detected on the +; serial_clock input. It is assumed that the interfacing device is +; shifting out 8 bits of data, MSB first, that is valid for some period +; of time after the falling edge. The measured latency between the +; triggering edge and completion of sampling the serial data (using +; the "acknowledge" pulse code below) ranges from 10us to 14us. It +; is believed that a 20us minimum serial clock period would provide +; reliable operation. +extern0_isr: + push psw + + ; sample the serial data line as early as possible + mov c, serial_data + +; debugging code: uncomment to generate an "acknowledge" pulse + setb serial_data_rx + nop + nop + clr serial_data_rx +; end of debugging code + + push acc + push reg0 + + ; shift the bit into our accumulator and decrement the bit counter + mov a, serial_acc + rlc a + mov serial_acc, a + djnz serial_bit_cnt, extern0_isr_done + + ; a complete byte has been received, transfer to receive buffer + mov a, rx_buf_head + inc a + cjne a, rx_buf_tail, store_received_byte + + ;If we got here, the recv buffer is full, so we just + ;discard this character. Maybe there should be an overrun + ;flag so the main program can know some data was lost... + sjmp ready_next_char + +store_received_byte: + mov rx_buf_head, a ;update rx_buf_head while it's still in Acc. + push dpl + push dph + mov dph, #rx_buf_page + mov dpl, a + mov a, serial_acc ;get the incoming data + movx @dptr, a ;and put it in the buffer + pop dph + pop dpl + +ready_next_char: + ; prepare for next byte + mov serial_bit_cnt, #8 + +extern0_isr_done: + pop reg0 + pop acc + pop psw + reti +;-------------------------------------------------------------------- timer0_isr: @@ -2022,6 +2117,7 @@ mov hscroll_t0_count, #0 setb hscroll_redraw pb_row_1: + jb clocked_serial_mode, timer0_isr_done ; no buttons in clocked serial mode mov a, pb_scan_state cjne a, #0, pb_row_2 mov c, pb_recv_1 @@ -2044,6 +2140,7 @@ setb pb_xmit_1 clr pb_xmit_2 setb pb_xmit_3 +timer0_isr_done: pop reg1 pop reg0 pop acc