STM32F4 rešitve
/*
* Main.s
*
* Created on: Aug 24, 2022
* Author: rozman
*/
.syntax unified
.cpu cortex-m7
.thumb
// Initializes USART3 device sequence of chars transmit/receive
// Sequence is sent on TX DMA channel, and then sequence of chars is received on RX DMA channel and retransmiteed back on next transmit.
// LED blinks on 0.5 secs, when TX and RX are working fluently.
///////////////////////////////////////////////////////////////////////////////
// Definitions
///////////////////////////////////////////////////////////////////////////////
// Definitions section. Define all the registers and
// constants here for code readability.
//----------------------
// Constants
//----------------------
.equ LEDDELAY, 64000
// For LOOPTC Software delay
// By default 64MHz internal HSI clock is enabled
// Internal loop takes approximately 1 cycle per subs/bne instruction pair
//----------------------
// Register Addresses
// You can find the base addresses for all peripherals from Memory Map section 2.3.2
// RM0433 on page 131. Then the offsets can be found on their relevant sections.
//----------------------
//----------------------
// RCC Registers
//----------------------
// RCC base address is 0x58024400
.equ RCC_BASE, 0x58024400 // RCC base reg
// AHB4ENR register offset is 0xE0
.equ RCC_AHB4ENR, 0x580244E0 // RCC AHB4 peripheral clock reg
//----------------------
// GPIO Registers
//----------------------
// GPIOI base address is 0x58022000
.equ GPIOI_BASE, 0x58022000 // GPIOI base address)
// MODER register offset is 0x00
.equ GPIOx_MODER, 0x00 // GPIOx port mode register
// ODR register offset is 0x14
.equ GPIOx_ODR, 0x14 // GPIOx output data register
// BSSR register offset is 0x18
.equ GPIOx_BSSR, 0x18 // GPIOx port set/reset register
// AFRH register offset is 0x24
.equ GPIOx_AFRH, 0x24 //
// Values for BSSR register - pin 13: LED is on, when GPIO is off
.equ LEDs_OFF, 0x00002000 // Setting pin to 1 -> LED is off
.equ LEDs_ON, 0x20000000 // Setting pin to 0 -> LED is on
//----------------------
// SysTick Registers
//----------------------
// SysTick Timer definitions
.equ SCS_BASE, 0xe000e000
.equ SCS_SYST_CSR, 0x10 // Control/Status register
.equ SCS_SYST_RVR, 0x14 // Value to countdown from
.equ SCS_SYST_CVR, 0x18 // Current value
.equ SYSTICK_RELOAD_1MS, 63999 //1 msec at 64MHz ...
//-----------------------------
// USART3 related definitions
//-----------------------------
// APB1LENR register offset is 0xE8
.equ RCC_APB1LENR, 0xE8 // RCC APB1LENR peripheral clock reg
// GPIOB base address is 0x58020400
.equ GPIOB_BASE, 0x58020400 // GPIOB base address)
.equ GPIO_AFRH_VALUE, 0x7700 // AF7 on PB10,11
// USART3 base address is 0x40004800
.equ USART3_BASE, 0x40004800 // USART3 base address)
// CRx registers
// CR1 register
.equ USART_CR1, 0x00 // CR1 register
.equ USART_CR1_VAL, 0b1101 // CR1 register value
// CRx registers
.equ USART_CR2, 0x04 // CR2 register
.equ USART_CR3, 0x08 // CR3 register
// BRR register
.equ USART_BRR, 0x0C // BRR register
.equ USART_BRR_VAL,556 // BRR register 64 000 000 / 115 200 = 555.55 = 556
// ISR, ICR registers
.equ USART_ISR, 0x1c // ISR register
.equ USART_ICR, 0x20 // ICR register
// Data registers
.equ USART_RDR, 0x24 // Receive Data Register
.equ USART_TDR, 0x28 // Transmit Data Register
//-----------------------------
// DMA related definitions
//-----------------------------
// AHB1ENR register offset is 0xE8
.equ RCC_AHB1ENR, 0xD8 // RCC AHB1ENR peripheral clock reg
// DMAMUX1 base address is 0x40020800
.equ DMAMUX1_BASE, 0x40020800 // DMAMUX1 base address
.equ DMAMUX1_C0CR, 0x00 // CR for Channel 0
.equ DMAMUX1_C1CR, 0x04 // CR for Channel 1
// DMA1 base address is 0x40020000
.equ DMA1_BASE, 0x40020000 // DMA1 base address
// DMA2 base address is 0x40020400
.equ DMA2_BASE, 0x40020400 // DMA2 base address
.equ DMA_USART3_TX_STREAM, 0 //Channel 0 on DMA1
.equ DMA_USART3_RX_STREAM, 1 //Channel 1 on DMA1
// DMA Registers definitions
.equ DMA_LISR, 0x00
.equ DMA_HISR, 0x04
.equ DMA_LIFCR, 0x08
.equ DMA_HIFCR, 0x0C
.equ DMA_SxCR_TX, 0x10 + 0x18 * DMA_USART3_TX_STREAM
.equ DMA_SxFCR_TX, 0x24 + 0x18 * DMA_USART3_TX_STREAM
.equ DMA_SxSNDTR_TX, 0x14 + 0x18 * DMA_USART3_TX_STREAM
.equ DMA_SxPAR_TX, 0x18 + 0x18 * DMA_USART3_TX_STREAM
.equ DMA_SxM0AR_TX, 0x1C + 0x18 * DMA_USART3_TX_STREAM
.equ DMA_SxCR_RX, 0x10 + 0x18 * DMA_USART3_RX_STREAM
.equ DMA_SxFCR_RX, 0x24 + 0x18 * DMA_USART3_RX_STREAM
.equ DMA_SxSNDTR_RX, 0x14 + 0x18 * DMA_USART3_RX_STREAM
.equ DMA_SxPAR_RX, 0x18 + 0x18 * DMA_USART3_RX_STREAM
.equ DMA_SxM0AR_RX, 0x1C + 0x18 * DMA_USART3_RX_STREAM
// Start of data section
.data
NIZ1: .space 12
NIZ2: .asciz "Testni niz!"
.space 0
.equ NIZ_LEN, 6
// Start of text section
.text
.type main, %function
.global main
.align
main:
bl INIT_IO // Priprava za kontrolo LED diode
bl INIT_TC // Priprava SysTick časovnika
bl INIT_USART3 // Priprava USART3 naprave
bl INIT_DMA // Priprava DMA naprave za prenose preko USART3
loop:
ldr r0,=NIZ2
mov r1,#NIZ_LEN
bl SND_DMA
// mov r0,r2
// bl SEND_UART
bl LED_ON // Vklop LED diode
mov r0,#500
// bl DELAY // Zakasnitev SW Delay: r0 x 1msec
bl DELAYTC // Zakasnitev SysTick : r0 x 1msec
// bl RECV_UART // will return only if character is received
// mov r2,r0
ldr r0,=NIZ1
mov r1,#NIZ_LEN
bl RCV_DMA
ldr r0,=NIZ1
ldr r1,=NIZ2
ldr r2, =NIZ_LEN
bl CHANGE
bl LED_OFF // Izlop LED diode
mov r0,#500
// bl DELAY // Zakasnitev SW Delay: r0 x 1msec
bl DELAYTC // Zakasnitev SysTick : r0 x 1msec
b loop // skok na vrstico loop:
__end: b __end
INIT_DMA:
push {r5, r6, lr}
// ------------- DMA1 Settings
// Enable DMA1 Peripheral Clock (bit 0 in AHB1ENR register)
ldr r6, =RCC_BASE // Load peripheral clock reg base address to r6
ldr r5, [r6,#RCC_AHB1ENR] // Read its content to r5
orr r5, #1 // Set bit 0 to enable DMA1 clock
str r5, [r6,#RCC_AHB1ENR] // Store result in peripheral clock register
ldr r6, =DMA1_BASE // Load DMA1 BASE address to r6
// ------- DMA1 TX Settings
// Disable DMA TX Channel
ldr r5, [r6,#DMA_SxCR_TX] // Read its content to r5
bic r5, #1
str r5, [r6,#DMA_SxCR_TX] // Store result
wt0_EN0:
ldr r5, [r6,#DMA_SxCR_TX] // wait until bit is read as 0
tst r5, #1
bne wt0_EN0
// Set MINC (increment memory pointer) and Direction (Memory->Peripheral)
orr r5,r5,#(0b10001 << 6) // b10=1 and bit7,6 = 01
str r5, [r6,#DMA_SxCR_TX] // Store result
// Enable direct mode
ldr r5, [r6,#DMA_SxFCR_TX] // Read its content to r5
bic r5, #0b100
str r5, [r6,#DMA_SxFCR_TX] // Store result
// ------- DMA1 RX Settings
// Disable DMA RX Channel
ldr r5, [r6,#DMA_SxCR_RX] // Read its content to r5
bic r5, #1
str r5, [r6,#DMA_SxCR_RX] // Store result
wt1_EN0:
ldr r5, [r6,#DMA_SxCR_RX] // wait until bit is read as 0
tst r5, #1
bne wt1_EN0
// Set MINC (increment memory pointer) and Direction (Memory<-Peripheral)
orr r5,r5,#(0b10000 << 6) // b10=1 and bit7,6 = 00
str r5, [r6,#DMA_SxCR_RX] // Store result
// Enable direct mode
ldr r5, [r6,#DMA_SxFCR_RX] // Read its content to r5
bic r5, #0b100
str r5, [r6,#DMA_SxFCR_RX] // Store result
// ------------- DMAMUX1 Settings
// Set channels to devices translations (multiplexing)
ldr r6, =DMAMUX1_BASE // Load reg base address to r6
mov r5,#46 // USART3_TX DMA Device Nr. is 46
str r5, [r6, DMAMUX1_C0CR] // DMAREQ for Channel 0 to USART3_TX
mov r5,#45 // USART3_Rx DMA Device Nr. is 45
str r5, [r6, DMAMUX1_C1CR] // DMAREQ for Channel 1 to USART3_RX
// ------------- USART3 Settings
ldr r6, =USART3_BASE // Load USART3 BASE address to r1
// Disable USART3
ldr r5, [r6,#USART_CR1] // Read its content to r5
bic r5, #1
str r5, [r6,#USART_CR1] // Store result
// Enable DMA Transmit and Receive for USART3
ldr r5, [r6, #USART_CR3]
orr r5, #(0b11<<6) // Set bits 7 and 6 to enable DMAT and DMAR bits
str r5, [r6,#USART_CR3] // Store result
// Enable USART3
ldr r6, =USART3_BASE // Load USART3 BASE address to r6
ldr r5, [r6,#USART_CR1] // Read its content to r5
orr r5, r5, #1
str r5, [r6,#USART_CR1] // Store result
pop {r5, r6, pc}
RCV_DMA:
push {r5, r6, lr}
ldr r6, =DMA1_BASE // Load reg base address to r6
WAIT_EN: // Wait EN bit to become zero
ldr r5, [r6, #DMA_SxCR_RX]
tst r5, #1
bne WAIT_EN
ldr r6, =DMA1_BASE // Load reg base address to r6
// Receive (RX) DMA Init
ldr r5, =USART3_BASE+USART_RDR // RX peripheral address to r5
str r5, [r6,#DMA_SxPAR_RX] // Store peripheral DMA pointer
str r0, [r6,#DMA_SxM0AR_RX] // Store address pointer
str r1, [r6,#DMA_SxSNDTR_RX] // Store number of units
// Clear flags in Status register
mov r5,#(0b111101<<6) // clear flags for Ch1 in ISR
str r5, [r6,# DMA_LIFCR] // Store
// Enable DMA Channel
ldr r5, [r6, #DMA_SxCR_RX]
orr r5, r5, #1
str r5, [r6, #DMA_SxCR_RX] // Enable channel
// Wait for the end of reception (TCIF
ldr r6, =DMA1_BASE // Load reg base address to r6
WAIT_RC:
ldr r5, [r6, #DMA_LISR]
tst r5, #(1 << 11) // TCIF1 flag
beq WAIT_RC
pop {r5, r6, pc}
SND_DMA:
push {r5, r6, lr}
ldr r6, =DMA1_BASE // Load reg base address to r6
WAIT_EN1: // Wait EN bit to become zero
ldr r5, [r6, #DMA_SxCR_TX]
tst r5, #1
bne WAIT_EN1
ldr r6, =DMA1_BASE // Load reg base address to r6
// Transmit (TX) DMA Init
ldr r5, =USART3_BASE+USART_TDR // RX peripheral address to r5
str r5, [r6,#DMA_SxPAR_TX] // Store result in peripheral DMA pointerclock register
str r0, [r6,#DMA_SxM0AR_TX] // Store address pointer
str r1, [r6,#DMA_SxSNDTR_TX] // Store result in peripheral DMA pointerclock register
// Clear flags in Status register
mov r5, #0b111101 // Clear all bits for channel 0
str r5, [r6,#DMA_LIFCR] // Store result in peripheral DMA pointerclock register
// Enable DMA Channel
ldr r6, =DMA1_BASE // Load reg base address to r6
ldr r5, [r6, #DMA_SxCR_TX]
orr r5, r5, #1
str r5, [r6, #DMA_SxCR_TX] // Enable channel
// Wait for the end of transmission
ldr r6, =USART3_BASE
WAIT_TC:
ldr r5, [r6, #USART_ISR]
tst r5, #(1 << 6) // Test TC bit
beq WAIT_TC
pop {r5, r6, pc}
CHANGE:
push {r3-r4,lr}
ch_zanka:
ldrb r4, [r0], #1
bic r3, r4, #0b100000
cmp r3, #'A'
blo pisi
cmp r3, #'Z'
bhi pisi
eor r4, r4, #0b100000 /*veliko crko spremeni v majhno*/
pisi:
strb r4, [r1], #1 /* shranimo v niz2*/
subs r2, r2, #1
bne ch_zanka
pop {r3-r4,pc}
INIT_USART3:
push {r0, r1, r2, lr}
// Enable USART3 Peripheral Clock (bit 18 in APB1LENR register)
ldr r1, =RCC_BASE // Load peripheral clock reg base address to r1
ldr r0, [r1,#RCC_APB1LENR] // Read its content to r0
orr r0, r0, #(1<<18) // Set bit 18 to enable USART3 clock
str r0, [r1,#RCC_APB1LENR] // Store result in peripheral clock register
// Enable GPIOB Peripheral Clock (bit 1 in AHB4ENR register)
ldr r1, = RCC_AHB4ENR // Load peripheral clock reg address to r6
ldr r0, [r1] // Read its content to r5
orr r0, r0, #0b10 // Set bit 1 to enable GPIOB clock
str r0, [r1] // Store result in peripheral clock register
ldr r1, =GPIOB_BASE // Load GPIOB BASE address to r1
// Make GPIOB Pina 10,11 as AF (bits 20:23 in MODER register)
ldr r0, [r1,#GPIOx_MODER] // Read GPIO_MODER content to r0
ldr r2, =0xFF0FFFFF // Clear mask
and r0, r0, r2 // Clear bits
orr r0, #0x00A00000 // Write 10 to bits
str r0, [r1,#GPIOx_MODER] // Store result in GPIO MODER register
// Make GPIOB Pina 10,11 as AF7 (bits 8:15 in AFRH register)
ldr r0, [r1,#GPIOx_AFRH] // Read GPIOB AFRH content to r0
ldr r2, =0xFFFF00FF // Clear mask
and r0, r0, r2 // Clear bits
orr r0, r0, #GPIO_AFRH_VALUE
str r0, [r1,#GPIOx_AFRH] // Store result in GPIOB AFRH register
ldr r1, =USART3_BASE // Load USART3 BASE address to r1
// Disable USART3
mov r0, #0
str r0, [r1,#USART_CR1] // Store result
// Set USART3 BaudRate
ldr r0, =USART_BRR_VAL
str r0, [r1,#USART_BRR] // Store result
// Start USART3
mov r0, #USART_CR1_VAL
str r0, [r1,#USART_CR1] // Store result
pop {r0, r1, r2, pc}
RECV_UART:
push {r1, r2, lr}
ldr r1, =USART3_BASE
RECV_LP:
ldr r2, [r1, #USART_ISR]
tst r2, #(1 << 5) // RXNE flag
beq RECV_LP
ldr r0, [r1, #USART_RDR]
pop {r1, r2, pc}
SEND_UART:
push {r1, r2, lr}
ldr r1, =USART3_BASE
SEND_LP:
ldr r2, [r1, #USART_ISR]
tst r2, #(1 << 7) // TXE flag
beq SEND_LP
str r0, [r1, #USART_TDR]
pop {r1, r2, pc}
INIT_TC:
push {r0, r1, lr}
ldr r1, =SCS_BASE
ldr r0, =SYSTICK_RELOAD_1MS
str r0, [r1, #SCS_SYST_RVR]
mov r0, #0
str r0, [r1, #SCS_SYST_CVR]
mov r0, #0b101
str r0, [r1, #SCS_SYST_CSR]
pop {r0, r1, pc}
INIT_IO:
push {r5, r6, lr}
// Enable GPIOI Peripheral Clock (bit 8 in AHB4ENR register)
ldr r6, = RCC_AHB4ENR // Load peripheral clock reg address to r6
ldr r5, [r6] // Read its content to r5
orr r5, #0x00000100 // Set bit 8 to enable GPIOI clock
str r5, [r6] // Store result in peripheral clock register
// Make GPIOI Pin13 as output pin (bits 27:26 in MODER register)
ldr r6, =GPIOI_BASE // Load GPIOD BASE address to r6
ldr r5, [r6,#GPIOx_MODER] // Read GPIOD_MODER content to r5
and r5, #0xF3FFFFFF // Clear bits 27-26 for P13
orr r5, #0x04000000 // Write 01 to bits 27-26 for P13
str r5, [r6] // Store result in GPIO MODER register
pop {r5, r6, pc}
LED_ON:
push {r5, r6, lr}
// Set GPIOx Pins to 0 (through BSSR register)
ldr r6, =GPIOI_BASE // Load GPIOI BASE address to r6
mov r5, #LEDs_ON
str r5, [r6,#GPIOx_BSSR] // Write to BSRR register
pop {r5, r6, pc}
LED_OFF:
push {r5, r6, lr}
// Set GPIOx Pins to 1 (through BSSR register)
ldr r6, =GPIOI_BASE // Load GPIOI BASE address to r6
mov r5, #LEDs_OFF
str r5, [r6,#GPIOx_BSSR] // Write to BSRR register
pop {r5, r6, pc}
// Delay with internal timer based loop approx. r0 x ms
DELAYTC:
push {r1, r2, lr}
ldr r1, =SCS_BASE
LOOPTC: ldr r2, [r1, #SCS_SYST_CSR]
tst r2, #0x10000 // COUNT_FLAG = 1 ?
beq LOOPTC
subs r0, r0, #1
bne LOOPTC
pop {r1, r2, pc}
// Delay with internal SW loop approx. r0 x ms
DELAY:
push {r1, lr}
MSEC: ldr r1,=LEDDELAY
LOOP: subs r1, r1, #1
bne LOOP
subs r0, r0, #1
bne MSEC
pop {r1, pc}
* Main.s
*
* Created on: Aug 24, 2022
* Author: rozman
*/
.syntax unified
.cpu cortex-m7
.thumb
// Initializes USART3 device sequence of chars transmit/receive
// Sequence is sent on TX DMA channel, and then sequence of chars is received on RX DMA channel and retransmiteed back on next transmit.
// LED blinks on 0.5 secs, when TX and RX are working fluently.
///////////////////////////////////////////////////////////////////////////////
// Definitions
///////////////////////////////////////////////////////////////////////////////
// Definitions section. Define all the registers and
// constants here for code readability.
//----------------------
// Constants
//----------------------
.equ LEDDELAY, 64000
// For LOOPTC Software delay
// By default 64MHz internal HSI clock is enabled
// Internal loop takes approximately 1 cycle per subs/bne instruction pair
//----------------------
// Register Addresses
// You can find the base addresses for all peripherals from Memory Map section 2.3.2
// RM0433 on page 131. Then the offsets can be found on their relevant sections.
//----------------------
//----------------------
// RCC Registers
//----------------------
// RCC base address is 0x58024400
.equ RCC_BASE, 0x58024400 // RCC base reg
// AHB4ENR register offset is 0xE0
.equ RCC_AHB4ENR, 0x580244E0 // RCC AHB4 peripheral clock reg
//----------------------
// GPIO Registers
//----------------------
// GPIOI base address is 0x58022000
.equ GPIOI_BASE, 0x58022000 // GPIOI base address)
// MODER register offset is 0x00
.equ GPIOx_MODER, 0x00 // GPIOx port mode register
// ODR register offset is 0x14
.equ GPIOx_ODR, 0x14 // GPIOx output data register
// BSSR register offset is 0x18
.equ GPIOx_BSSR, 0x18 // GPIOx port set/reset register
// AFRH register offset is 0x24
.equ GPIOx_AFRH, 0x24 //
// Values for BSSR register - pin 13: LED is on, when GPIO is off
.equ LEDs_OFF, 0x00002000 // Setting pin to 1 -> LED is off
.equ LEDs_ON, 0x20000000 // Setting pin to 0 -> LED is on
//----------------------
// SysTick Registers
//----------------------
// SysTick Timer definitions
.equ SCS_BASE, 0xe000e000
.equ SCS_SYST_CSR, 0x10 // Control/Status register
.equ SCS_SYST_RVR, 0x14 // Value to countdown from
.equ SCS_SYST_CVR, 0x18 // Current value
.equ SYSTICK_RELOAD_1MS, 63999 //1 msec at 64MHz ...
//-----------------------------
// USART3 related definitions
//-----------------------------
// APB1LENR register offset is 0xE8
.equ RCC_APB1LENR, 0xE8 // RCC APB1LENR peripheral clock reg
// GPIOB base address is 0x58020400
.equ GPIOB_BASE, 0x58020400 // GPIOB base address)
.equ GPIO_AFRH_VALUE, 0x7700 // AF7 on PB10,11
// USART3 base address is 0x40004800
.equ USART3_BASE, 0x40004800 // USART3 base address)
// CRx registers
// CR1 register
.equ USART_CR1, 0x00 // CR1 register
.equ USART_CR1_VAL, 0b1101 // CR1 register value
// CRx registers
.equ USART_CR2, 0x04 // CR2 register
.equ USART_CR3, 0x08 // CR3 register
// BRR register
.equ USART_BRR, 0x0C // BRR register
.equ USART_BRR_VAL,556 // BRR register 64 000 000 / 115 200 = 555.55 = 556
// ISR, ICR registers
.equ USART_ISR, 0x1c // ISR register
.equ USART_ICR, 0x20 // ICR register
// Data registers
.equ USART_RDR, 0x24 // Receive Data Register
.equ USART_TDR, 0x28 // Transmit Data Register
//-----------------------------
// DMA related definitions
//-----------------------------
// AHB1ENR register offset is 0xE8
.equ RCC_AHB1ENR, 0xD8 // RCC AHB1ENR peripheral clock reg
// DMAMUX1 base address is 0x40020800
.equ DMAMUX1_BASE, 0x40020800 // DMAMUX1 base address
.equ DMAMUX1_C0CR, 0x00 // CR for Channel 0
.equ DMAMUX1_C1CR, 0x04 // CR for Channel 1
// DMA1 base address is 0x40020000
.equ DMA1_BASE, 0x40020000 // DMA1 base address
// DMA2 base address is 0x40020400
.equ DMA2_BASE, 0x40020400 // DMA2 base address
.equ DMA_USART3_TX_STREAM, 0 //Channel 0 on DMA1
.equ DMA_USART3_RX_STREAM, 1 //Channel 1 on DMA1
// DMA Registers definitions
.equ DMA_LISR, 0x00
.equ DMA_HISR, 0x04
.equ DMA_LIFCR, 0x08
.equ DMA_HIFCR, 0x0C
.equ DMA_SxCR_TX, 0x10 + 0x18 * DMA_USART3_TX_STREAM
.equ DMA_SxFCR_TX, 0x24 + 0x18 * DMA_USART3_TX_STREAM
.equ DMA_SxSNDTR_TX, 0x14 + 0x18 * DMA_USART3_TX_STREAM
.equ DMA_SxPAR_TX, 0x18 + 0x18 * DMA_USART3_TX_STREAM
.equ DMA_SxM0AR_TX, 0x1C + 0x18 * DMA_USART3_TX_STREAM
.equ DMA_SxCR_RX, 0x10 + 0x18 * DMA_USART3_RX_STREAM
.equ DMA_SxFCR_RX, 0x24 + 0x18 * DMA_USART3_RX_STREAM
.equ DMA_SxSNDTR_RX, 0x14 + 0x18 * DMA_USART3_RX_STREAM
.equ DMA_SxPAR_RX, 0x18 + 0x18 * DMA_USART3_RX_STREAM
.equ DMA_SxM0AR_RX, 0x1C + 0x18 * DMA_USART3_RX_STREAM
// Start of data section
.data
NIZ1: .space 12
NIZ2: .asciz "Testni niz!"
.space 0
.equ NIZ_LEN, 6
// Start of text section
.text
.type main, %function
.global main
.align
main:
bl INIT_IO // Priprava za kontrolo LED diode
bl INIT_TC // Priprava SysTick časovnika
bl INIT_USART3 // Priprava USART3 naprave
bl INIT_DMA // Priprava DMA naprave za prenose preko USART3
loop:
ldr r0,=NIZ2
mov r1,#NIZ_LEN
bl SND_DMA
// mov r0,r2
// bl SEND_UART
bl LED_ON // Vklop LED diode
mov r0,#500
// bl DELAY // Zakasnitev SW Delay: r0 x 1msec
bl DELAYTC // Zakasnitev SysTick : r0 x 1msec
// bl RECV_UART // will return only if character is received
// mov r2,r0
ldr r0,=NIZ1
mov r1,#NIZ_LEN
bl RCV_DMA
ldr r0,=NIZ1
ldr r1,=NIZ2
ldr r2, =NIZ_LEN
bl CHANGE
bl LED_OFF // Izlop LED diode
mov r0,#500
// bl DELAY // Zakasnitev SW Delay: r0 x 1msec
bl DELAYTC // Zakasnitev SysTick : r0 x 1msec
b loop // skok na vrstico loop:
__end: b __end
INIT_DMA:
push {r5, r6, lr}
// ------------- DMA1 Settings
// Enable DMA1 Peripheral Clock (bit 0 in AHB1ENR register)
ldr r6, =RCC_BASE // Load peripheral clock reg base address to r6
ldr r5, [r6,#RCC_AHB1ENR] // Read its content to r5
orr r5, #1 // Set bit 0 to enable DMA1 clock
str r5, [r6,#RCC_AHB1ENR] // Store result in peripheral clock register
ldr r6, =DMA1_BASE // Load DMA1 BASE address to r6
// ------- DMA1 TX Settings
// Disable DMA TX Channel
ldr r5, [r6,#DMA_SxCR_TX] // Read its content to r5
bic r5, #1
str r5, [r6,#DMA_SxCR_TX] // Store result
wt0_EN0:
ldr r5, [r6,#DMA_SxCR_TX] // wait until bit is read as 0
tst r5, #1
bne wt0_EN0
// Set MINC (increment memory pointer) and Direction (Memory->Peripheral)
orr r5,r5,#(0b10001 << 6) // b10=1 and bit7,6 = 01
str r5, [r6,#DMA_SxCR_TX] // Store result
// Enable direct mode
ldr r5, [r6,#DMA_SxFCR_TX] // Read its content to r5
bic r5, #0b100
str r5, [r6,#DMA_SxFCR_TX] // Store result
// ------- DMA1 RX Settings
// Disable DMA RX Channel
ldr r5, [r6,#DMA_SxCR_RX] // Read its content to r5
bic r5, #1
str r5, [r6,#DMA_SxCR_RX] // Store result
wt1_EN0:
ldr r5, [r6,#DMA_SxCR_RX] // wait until bit is read as 0
tst r5, #1
bne wt1_EN0
// Set MINC (increment memory pointer) and Direction (Memory<-Peripheral)
orr r5,r5,#(0b10000 << 6) // b10=1 and bit7,6 = 00
str r5, [r6,#DMA_SxCR_RX] // Store result
// Enable direct mode
ldr r5, [r6,#DMA_SxFCR_RX] // Read its content to r5
bic r5, #0b100
str r5, [r6,#DMA_SxFCR_RX] // Store result
// ------------- DMAMUX1 Settings
// Set channels to devices translations (multiplexing)
ldr r6, =DMAMUX1_BASE // Load reg base address to r6
mov r5,#46 // USART3_TX DMA Device Nr. is 46
str r5, [r6, DMAMUX1_C0CR] // DMAREQ for Channel 0 to USART3_TX
mov r5,#45 // USART3_Rx DMA Device Nr. is 45
str r5, [r6, DMAMUX1_C1CR] // DMAREQ for Channel 1 to USART3_RX
// ------------- USART3 Settings
ldr r6, =USART3_BASE // Load USART3 BASE address to r1
// Disable USART3
ldr r5, [r6,#USART_CR1] // Read its content to r5
bic r5, #1
str r5, [r6,#USART_CR1] // Store result
// Enable DMA Transmit and Receive for USART3
ldr r5, [r6, #USART_CR3]
orr r5, #(0b11<<6) // Set bits 7 and 6 to enable DMAT and DMAR bits
str r5, [r6,#USART_CR3] // Store result
// Enable USART3
ldr r6, =USART3_BASE // Load USART3 BASE address to r6
ldr r5, [r6,#USART_CR1] // Read its content to r5
orr r5, r5, #1
str r5, [r6,#USART_CR1] // Store result
pop {r5, r6, pc}
RCV_DMA:
push {r5, r6, lr}
ldr r6, =DMA1_BASE // Load reg base address to r6
WAIT_EN: // Wait EN bit to become zero
ldr r5, [r6, #DMA_SxCR_RX]
tst r5, #1
bne WAIT_EN
ldr r6, =DMA1_BASE // Load reg base address to r6
// Receive (RX) DMA Init
ldr r5, =USART3_BASE+USART_RDR // RX peripheral address to r5
str r5, [r6,#DMA_SxPAR_RX] // Store peripheral DMA pointer
str r0, [r6,#DMA_SxM0AR_RX] // Store address pointer
str r1, [r6,#DMA_SxSNDTR_RX] // Store number of units
// Clear flags in Status register
mov r5,#(0b111101<<6) // clear flags for Ch1 in ISR
str r5, [r6,# DMA_LIFCR] // Store
// Enable DMA Channel
ldr r5, [r6, #DMA_SxCR_RX]
orr r5, r5, #1
str r5, [r6, #DMA_SxCR_RX] // Enable channel
// Wait for the end of reception (TCIF
ldr r6, =DMA1_BASE // Load reg base address to r6
WAIT_RC:
ldr r5, [r6, #DMA_LISR]
tst r5, #(1 << 11) // TCIF1 flag
beq WAIT_RC
pop {r5, r6, pc}
SND_DMA:
push {r5, r6, lr}
ldr r6, =DMA1_BASE // Load reg base address to r6
WAIT_EN1: // Wait EN bit to become zero
ldr r5, [r6, #DMA_SxCR_TX]
tst r5, #1
bne WAIT_EN1
ldr r6, =DMA1_BASE // Load reg base address to r6
// Transmit (TX) DMA Init
ldr r5, =USART3_BASE+USART_TDR // RX peripheral address to r5
str r5, [r6,#DMA_SxPAR_TX] // Store result in peripheral DMA pointerclock register
str r0, [r6,#DMA_SxM0AR_TX] // Store address pointer
str r1, [r6,#DMA_SxSNDTR_TX] // Store result in peripheral DMA pointerclock register
// Clear flags in Status register
mov r5, #0b111101 // Clear all bits for channel 0
str r5, [r6,#DMA_LIFCR] // Store result in peripheral DMA pointerclock register
// Enable DMA Channel
ldr r6, =DMA1_BASE // Load reg base address to r6
ldr r5, [r6, #DMA_SxCR_TX]
orr r5, r5, #1
str r5, [r6, #DMA_SxCR_TX] // Enable channel
// Wait for the end of transmission
ldr r6, =USART3_BASE
WAIT_TC:
ldr r5, [r6, #USART_ISR]
tst r5, #(1 << 6) // Test TC bit
beq WAIT_TC
pop {r5, r6, pc}
CHANGE:
push {r3-r4,lr}
ch_zanka:
ldrb r4, [r0], #1
bic r3, r4, #0b100000
cmp r3, #'A'
blo pisi
cmp r3, #'Z'
bhi pisi
eor r4, r4, #0b100000 /*veliko crko spremeni v majhno*/
pisi:
strb r4, [r1], #1 /* shranimo v niz2*/
subs r2, r2, #1
bne ch_zanka
pop {r3-r4,pc}
INIT_USART3:
push {r0, r1, r2, lr}
// Enable USART3 Peripheral Clock (bit 18 in APB1LENR register)
ldr r1, =RCC_BASE // Load peripheral clock reg base address to r1
ldr r0, [r1,#RCC_APB1LENR] // Read its content to r0
orr r0, r0, #(1<<18) // Set bit 18 to enable USART3 clock
str r0, [r1,#RCC_APB1LENR] // Store result in peripheral clock register
// Enable GPIOB Peripheral Clock (bit 1 in AHB4ENR register)
ldr r1, = RCC_AHB4ENR // Load peripheral clock reg address to r6
ldr r0, [r1] // Read its content to r5
orr r0, r0, #0b10 // Set bit 1 to enable GPIOB clock
str r0, [r1] // Store result in peripheral clock register
ldr r1, =GPIOB_BASE // Load GPIOB BASE address to r1
// Make GPIOB Pina 10,11 as AF (bits 20:23 in MODER register)
ldr r0, [r1,#GPIOx_MODER] // Read GPIO_MODER content to r0
ldr r2, =0xFF0FFFFF // Clear mask
and r0, r0, r2 // Clear bits
orr r0, #0x00A00000 // Write 10 to bits
str r0, [r1,#GPIOx_MODER] // Store result in GPIO MODER register
// Make GPIOB Pina 10,11 as AF7 (bits 8:15 in AFRH register)
ldr r0, [r1,#GPIOx_AFRH] // Read GPIOB AFRH content to r0
ldr r2, =0xFFFF00FF // Clear mask
and r0, r0, r2 // Clear bits
orr r0, r0, #GPIO_AFRH_VALUE
str r0, [r1,#GPIOx_AFRH] // Store result in GPIOB AFRH register
ldr r1, =USART3_BASE // Load USART3 BASE address to r1
// Disable USART3
mov r0, #0
str r0, [r1,#USART_CR1] // Store result
// Set USART3 BaudRate
ldr r0, =USART_BRR_VAL
str r0, [r1,#USART_BRR] // Store result
// Start USART3
mov r0, #USART_CR1_VAL
str r0, [r1,#USART_CR1] // Store result
pop {r0, r1, r2, pc}
RECV_UART:
push {r1, r2, lr}
ldr r1, =USART3_BASE
RECV_LP:
ldr r2, [r1, #USART_ISR]
tst r2, #(1 << 5) // RXNE flag
beq RECV_LP
ldr r0, [r1, #USART_RDR]
pop {r1, r2, pc}
SEND_UART:
push {r1, r2, lr}
ldr r1, =USART3_BASE
SEND_LP:
ldr r2, [r1, #USART_ISR]
tst r2, #(1 << 7) // TXE flag
beq SEND_LP
str r0, [r1, #USART_TDR]
pop {r1, r2, pc}
INIT_TC:
push {r0, r1, lr}
ldr r1, =SCS_BASE
ldr r0, =SYSTICK_RELOAD_1MS
str r0, [r1, #SCS_SYST_RVR]
mov r0, #0
str r0, [r1, #SCS_SYST_CVR]
mov r0, #0b101
str r0, [r1, #SCS_SYST_CSR]
pop {r0, r1, pc}
INIT_IO:
push {r5, r6, lr}
// Enable GPIOI Peripheral Clock (bit 8 in AHB4ENR register)
ldr r6, = RCC_AHB4ENR // Load peripheral clock reg address to r6
ldr r5, [r6] // Read its content to r5
orr r5, #0x00000100 // Set bit 8 to enable GPIOI clock
str r5, [r6] // Store result in peripheral clock register
// Make GPIOI Pin13 as output pin (bits 27:26 in MODER register)
ldr r6, =GPIOI_BASE // Load GPIOD BASE address to r6
ldr r5, [r6,#GPIOx_MODER] // Read GPIOD_MODER content to r5
and r5, #0xF3FFFFFF // Clear bits 27-26 for P13
orr r5, #0x04000000 // Write 01 to bits 27-26 for P13
str r5, [r6] // Store result in GPIO MODER register
pop {r5, r6, pc}
LED_ON:
push {r5, r6, lr}
// Set GPIOx Pins to 0 (through BSSR register)
ldr r6, =GPIOI_BASE // Load GPIOI BASE address to r6
mov r5, #LEDs_ON
str r5, [r6,#GPIOx_BSSR] // Write to BSRR register
pop {r5, r6, pc}
LED_OFF:
push {r5, r6, lr}
// Set GPIOx Pins to 1 (through BSSR register)
ldr r6, =GPIOI_BASE // Load GPIOI BASE address to r6
mov r5, #LEDs_OFF
str r5, [r6,#GPIOx_BSSR] // Write to BSRR register
pop {r5, r6, pc}
// Delay with internal timer based loop approx. r0 x ms
DELAYTC:
push {r1, r2, lr}
ldr r1, =SCS_BASE
LOOPTC: ldr r2, [r1, #SCS_SYST_CSR]
tst r2, #0x10000 // COUNT_FLAG = 1 ?
beq LOOPTC
subs r0, r0, #1
bne LOOPTC
pop {r1, r2, pc}
// Delay with internal SW loop approx. r0 x ms
DELAY:
push {r1, lr}
MSEC: ldr r1,=LEDDELAY
LOOP: subs r1, r1, #1
bne LOOP
subs r0, r0, #1
bne MSEC
pop {r1, pc}
Last modified: Friday, 6 January 2023, 10:49 AM