        .data
        .align 16
		.bss	DMA_control_table,1024  ; 1K per table align to a 1K page boundary
		.bss    Block_to_send_256_bytes,256
        .sect ".intvecs"

		.word   0x20040000    ;    Stack pointer start address top of SRAM
        .word    program_start  ;   jump to code start
     .text
    .thumb

program_start:

;  SETUP GPIO - enable application ports
 
    MOVT R0, #0x400F
    MOVW R0, #0xE608
    LDR R1, [R0]
    ORR R1, R1, #0x0002+0x0010+0x0020
    STR R1, [R0]    

;  set GPIO pin association to SSI for PB5      
    MOVT R0, #0x4005
    MOVW R0, #0x952C
    LDR R1, [R0]
    ORR R1, R1, #0x00F00000
    STR R1, [R0]     

; set GPIO pin associations to SSI for PE4 PE5 */
    MOVT R0, #0x4005
    MOVW R0, #0xC52C
    LDR R1, [R0]
    ORR R1, R1, #0x000F0000+0x00F00000
    STR R1, [R0]

; set PB5 to alternate function - PB5 (SPI Clk) */
    MOVT R0, #0x4005
    MOVW R0, #0x9420
    LDR R1, [R0]                    
    ORR R1, R1, #0x20
    STR R1, [R0]               

; set PR4 & PE5 to alternate functions - PE4 (SPI data out) PE5 (SPI data in) */
    MOVT R0, #0x4005
    MOVW R0, #0xC420
    LDR R1, [R0]                    
    ORR R1, R1, #0x10+0x20
    STR R1, [R0] 

; Enable pin PB5 */
    MOVT R0, #0x4005
    MOVW R0, #0x951C
    LDR R1, [R0]
    ORR R1, R1, #0x20
    STR R1, [R0]   

; Enable pins PE4 & PE5 */
    MOVT R0, #0x4005
    MOVW R0, #0xC51C
    LDR R1, [R0]
    ORR R1, R1, #0x10+0x20
    STR R1, [R0]   

; END OF GPIO SETUP */
    
; START OF DMA INITIALISATION */
; Enable DMA module */
    MOVT R0, #0x400F
    MOVW R0, #0xE60C
    LDR R1, [R0]
    ORR R1, R1, #0x00000001
    STR R1, [R0] 

; Reset the DMA controller module */
    MOVT R0, #0x400F
    MOVW R0, #0xE50C
    LDR R1, [R0]
    ORR R1, R1, #0x00000001
    STR R1, [R0]
    LDR R1, [R0]
    BICS R1, R1, #0x00000001
    STR R1, [R0]

; Wait for the DMA module to complete its initialisation */
    MOVT R0, #0x400F
    MOVW R0, #0xEA0C
wait_for_dma_module:
    LDR R1, [R0]
    TSTS R1, #0x00000001
    BEQ wait_for_dma_module

; enable DMA controller */
    MOVT R0, #0x400F
    MOVW R0, #0xF004
    LDR R1, [R0]
    ORR R1, R1, #0x00000001
    STR R1, [R0]

; program channel control table base address */
    MOVT R0, #0x2000
    MOVW R0, #0x0000
    MOVT R1, #0x400F
    MOVW R1, #0xF008
    LDR R2, [R1]
    LSR R0, R0, #10
    BFI R2, R0, #10, #22  
    STR R2, [R1]

; Set DMA channel 11 channel / priority. See Table 9-1 on page 680 & 730 for channel assignments. */

    MOVT R0, #0x400F
    MOVW R0, #0xF514
    LDR R1, [R0]
    MOV R2, #1
    BFI R1, R2, #12, #3
    STR R1, [R0]

; Set DMA Channel 11 to default priority */
    MOVT R0, #0x400F
    MOVW R0, #0xF03C
    LDR R1, [R0]
    ORR R1, R1, #0x00000800
    STR R1,  [R0] 

; Enable DMA Channel 11 primary control structure */
    MOVT R0, #0x400F
    MOVW R0, #0xF034
    LDR R1, [R0]
    ORR R1, R1, #0x00000800
    STR R1, [R0]

; Enable single and burst requests for channel 11 */
    MOVT R0, #0x400F
    MOVW R0, #0xF01C
    LDR R1, [R0]
    ORR R1, R1, #0x00000800
    STR R1, [R0]

; Allow µDMA controller to recognise requests for channel 11. */
    MOVT R0, #0x400F
    MOVW R0, #0xF024
    LDR R1, [R0]
    ORR R1, R1, #0x00000800 ; Channel 11
    STR R1, [R0]

; DMA Channel 11 control structure configuration */
; Set  DMA Channel 11 source end pointer to end of block */
    MOVT R4, #0x2000
    MOVW R4, #0x00B0
    MOVT R1, #0x2000
    MOVW R1, #0x03FF
    STR R1, [R4] 

; Set  DMA Channel 11 destination end pointer. Destination address not incrementing ( ie the DSTINC field in the DMACHCTL register is 0x3) */    
    MOVT R0, #0x2000
    MOVW R0, #0x00B4
    MOVT R7, #0x4000
    MOVW R7, #0x9008
    STR R7, [R4]

; Set DMA Channel 11 control word */
    MOVT R0, #0x2000
    MOVW R0, #0x00B8
    MOVT R1, #0xC000
    MOVW R1, #0x8FF1
    STR R1, [R0] 

; Enable DMA channel*/
    MOVT R0, #0x400F
    MOVW R0, #0xF028
    LDR R1, [R0]
    ORR R1, R1, #0x00000800
    STR R1, [R0]
; END OF DMA INITIALISATION */

; START OF SSI1 INITIALISATION */
; If initializing out of reset, ensure that the SSE bit in the SSICR1 register is clear before making any configuration changes.*/

; Enable_SSI1 module clock */
    MOVT R1, #0x400F
    MOVW R1, #0xE61C
    LDR R0, [R1]
    ORR R0, R0, #0x00000002
    STR R0, [R1]

; Reset SSI1 module */
    
     MOVT R0, #0x400F
     MOVW R0, #0xE51C
     LDR R1, [R0]
     ORR R1, R1, #0x00000001
     STR R1, [R0]  ; SSI1 in reset
     LDR R1, [R0]
     BICS R1, R1, #0x00000001
     STR R1, [R0]  ; SSI1 released from reset

; Wait for SSI1 module to be ready for access */
    MOVT R0, #0x400F
    MOVW R0, #0xEA1C
wait_for_SSI1_module:
    LDR R1, [R0]
    TSTS R1, #0x00000002
    BEQ wait_for_SSI1_module
       
; Configure the QSSI clock source by writing to the SSICC register. */

; Disable SSI1 before any setup is done */
    MOVT R0, #0x4000
    MOVW R0, #0x9004
    MOVT R1, #0x0000
    MOVW R1, #0x0000
    STR R1, [R0]  ; update QSSI1_BASE+SSICR1

; Set CPSDVSR prescale value */ 
    MOVT R0, #0x4000
    MOVW R0, #0x9010
    MOVT R0, #0x0000
    MOVW R0, #0x00FE
    STR R1, [R0]
      
;All bits SSICR0 can only be updated while SSE=0 (ie QSSI1 is disabled) */ 
    MOVT R0, #0x4000
    MOVW R0, #0x9000
    MOVT R0, #0x0000
    MOVW R0, #0x02C7
    STR R1, [R0]
     
; Enable DMA for SSI1 TX FIFO in SSI1 module, after configuring the DMA module */
    MOVT R5, #0x4000
    MOVW R5, #0x9024
    LDR R6, [R5]
    ORR R6, R6, #0x02
    STR R6, [R5]

; Unmask IRQs*/
    MOVT R5, #0x4000
    MOVW R5, #0x9014
    LDR R1, [R5]
    ORR R1, R1, #0x00000020+0x00000008
    STR R1, [R5]

; Enable SSI1 now setup complete so enable SSI1 */
    MOVT R0, #0x4000
    MOVW R0, #0x9004
    LDR R1, [R0]
    ORR R1, R1, #0x00000002
    STR R1, [R0] 

; END OF SSI1 INITIALISATION */

code_end:
    B code_end

    .end