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