Quantcast
Channel: Microcontrollers
Viewing all articles
Browse latest Browse all 216607

Forum Post: USCI_B0 SPI Master that sends data chunks from any buffer (assembler)

$
0
0

My routine that uses TX- IRQ to send chunks of data without main-routine intervention.(not fully tested)
Most examples uses hard-wait-loop to send each character, though not too bad as SPI rate is normally set high.

My example snippets below does
with the use of a macro point to a memory location you want to start to send from and how many bytes.
and also flag 1 = partial data don't pull CSn high as more data is coming. 
2 = stayawake, main routine will not wait (sleep) for this SPI chunk to be completely sent before going on.

MISO pin P1.6  have it's pull-up resistor set as some IC floats when it's enable/CS is off.
There are 3 ways to start a SPI transfer, move first byte to UCB0TXBUF, enable IRQ or set IRQ Flag.
I use the later in my routine
You would need to add some timer or button press etc to initiate the main routine.

This code below you could point to a header in ram and then a larger chunk in flash and send together.
You could probably dedicate R15 to R12 to SPI routine and not use Ram for pointers, if wanted.
I will add spi_read next, most IC are asynchronous and you send 0s to start reading after you first wrote some bytes

#include  "msp430G2553.h"  spiCSpin        EQU  1<<4        ; ChipSelect_n is on Px.4 spiCSport       EQU  P1OUT       ; ChipSelect_n is on P1.x SpiBufSize      EQU  64  spi_send macro text,len,flag              bic.b   #spiCSpin,&spiCSport          ; set CS active low        mov.w   #text,&spi_pnt                ; 16bit pointer       mov.b   #len,&spi_len                 ; send xx bytes               if _args == 2                         ; was no flag value included?          mov.b   #0,&spi_flag                ; set flags to 0 as non was included         bis.b   #UCB0TXIFG,&IFG2            ; set IRQ flag so SPI starts         bis.w   #LPM3+GIE,SR                ; CPU off, enable interrupts then to sleep          exitm         endif        mov.b   #flag,&spi_flag               ; set flags (like partial data, stayawake etc)         bis.b   #UCB0TXIFG,&IFG2              ; set IRQ flag so SPI starts       if flag &BIT1 == BIT1                 ; test BIT1 (stayawake flag)                                exitm        endif          bis.w   #LPM3+GIE,SR                ; CPU off, enable interrupts then to sleep           endm      ;***********************************************************************************                   ORG     0200h       ; start of ram on all devices             spi_buffer  ds8     SpiBufSize  ; reserve default 64bytes spi_len     ds8     1           ; reserve 1 byte for lenght counter spi_flag    ds8     1           ; 2= sleep  EVEN spi_pnt     ds16    1           ; 16bit spi buffer pointer              ORG     0E000h      ; start of flash ram for a 8k device    main        mov.w   #0x300,SP               ; Initialize stackpointer (on 256 ram)             mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop WDT             mov.b   &CALBC1_1MHZ,&BCSCTL1   ; Set DCO to factory calibrate 1MHz               mov.b   &CALDCO_1MHZ,&DCOCTL             bis.b   #1<<0,&P1DIR            ; P1.0 LED as output                          bic.b   #1<<0,&P1OUT            ; P1.0 LED off                          bis.b   #UCSWRST,&UCB0CTL1      ; Set UCSWRST (USCI Software Reset)             bis.b   #UCMSB+UCMST+UCSYNC,&UCB0CTL0 ; 3-pin, 8-bit SPI master             bis.b   #UCSSEL_2,&UCB0CTL1     ; Use SMCLK             bis.b   #08h,&UCB0BR0           ; and divide it by 8             clr.b   &UCB0BR1                ; the lower rate register              bis.b   #BIT5+BIT6+BIT7,&P1SEL  ; P1.x set as SPI pins (manual page 49)             bis.b   #BIT5+BIT6+BIT7,&P1SEL2 ; P1.x set as SPI pins                    bis.b   #1<<6,&P1REN            ; P1.6 (MISO) Pull Resistor             bis.b   #1<<6,&P1OUT            ; P1.6 Make it pull-up              bic.b   #UCSWRST,&UCB0CTL1      ; Initialize USCI state machine             bis.b   #UCB0TXIE,&IE2          ; Enable USCI_B0 TX interrupt                                                mainloop    bis.w   #LPM3+GIE,SR            ; CPU off, enable interrupts then got to deep sleep                                             ; your code below to run if CPU comes back on             xor.b   #1<<0,&P1OUT            ; P1.0 LED on/off             spi_send spi_buffer, 12, 1      ; macro to start a SPI TX_Irq transfer, partial_data,sleep             spi_send flashdata,200,2        ; SPI TX_Irq transfer, last part,no sleep                         jmp     mainloop                ; go back to sleep  flashdata  ds8 200                          ; just an example   ;-------------------------------------------------------------------------------            USCIAB0TX_ISR;          Shared A0 & B0 Transmit             bit.b   #UCB0TXIFG, &IFG2       ; USCI_B0 Transmit Interrupt?             jnz     USCIB0_TX_ISR           ; jmp if is was B0  USCIA0_TX_ISR             ; A write to UCA0TXBUF would also clear UCA0TXIFG             bic.b   #UCA0TXIFG,&IFG2        ; Clear IRQ flag if not done above             RETI                          USCIB0_TX_ISR             sub.b   #1,&spi_len             jz      spibuffdone             mov.w   &spi_pnt,R14             mov.b   @R14,&UCB0TXBUF         ; iniate transmit of byte             add.w   #1,&spi_pnt             ; move up to next byte             reti     spibuffdone              bic.b   #UCB0TXIFG,&IFG2        ; Clear IRQ flag             bit.b   #BIT0,&spi_flag         ; Partial_data flag set?             jnz     keepCSlow             bis.b   #spiCSpin,&spiCSport    ; set high as active low keepCSlow   bit.b   #BIT1,&spi_flag         ; stayawake flag was used?             jz      spiwakeup               ; jmp if it was not             reti                            ; leave it as it was spiwakeup   bic.w   #LPM3,0(SP)             ; Exit LPM3 on reti = run main prog                reti                          ;------------------------------------------------------------------------------- ;                  blank isr routines  USCIAB0RX_ISR NMI_ISR   WDT_ISR             reti  ;------------------------------------------------------------------------------- ;           Interrupt Vectors ;-------------------------------------------------------------------------------   COMMON  INTVEC             ; Interrupt Vector base 0xFFE0    ORG   USCIAB0TX_VECTOR    /* 0xFFEC USCI A0/B0 Transmit */   DW    USCIAB0TX_ISR   ORG   USCIAB0RX_VECTOR    /* 0xFFEE USCI A0/B0 Receive */   DW    USCIAB0RX_ISR   ORG   NMI_VECTOR          /* 0xFFFC Non-maskable */   DW    NMI_ISR   ORG   RESET_VECTOR        /* 0xFFFE Reset [Highest Priority] */   DW    main   END


Viewing all articles
Browse latest Browse all 216607

Trending Articles