program torque_vfd_comm;
uses cortexm3, stm32f103fw;
{$O-}
const
Serial_buffer_size = 7;
DMA_CHANNEL4 = 3;
PERIPH_BASE = $40000000;
AHBPERIPH_BASE= PERIPH_BASE + $00020000;
DMA1_Channel2_BASE= AHBPERIPH_BASE + $0000001C;
DMA1_Channel4_BASE= AHBPERIPH_BASE + $00000044;
type
TDMA_Channel_Registers = record
CCR : longword;
CNDTR : longword;
CPAR : longword;
CMAR : longword;
end;
var
TXBuffer1: Array [0..Serial_buffer_size-1] of byte;
TXBuffer3: Array [0..Serial_buffer_size-1] of byte;
Usart_ini: TUSART_InitTypeDef;
NVIC_Ini: TNVIC_InitTypeDef;
GPIO_InitStruct: TGPIO_InitTypeDef;
RCC_Clocks: TRCC_ClocksTypeDef;
DMA1_Channel4 : TDMA_Channel_Registers absolute DMA1_Channel4_BASE;
DMA1_Channel2 : TDMA_Channel_Registers absolute DMA1_Channel2_BASE;
i : integer;
procedure DMA1_Channel2_global_interrupt; public name 'DMA2_Channel1_global_interrupt'; interrupt;
Begin
DMA1.IFCR:= DMA1_FLAG_GL2;
end;
procedure DMA1_Channel4_global_interrupt; public name 'DMA4_Channel1_global_interrupt'; interrupt;
Begin
DMA1.IFCR:= DMA1_FLAG_GL4;
end;
procedure USART1_SendBytesViaDMA(var Data : array of byte; const count : integer = -1);
begin
//Disable DMA, Transfer Complete IRQ Read from Memory No Circular Mode No Periph Inc Memory Inc 8bit periph 8bit mem prio0
DMA1_Channel4.CCR := %000000010010010;
if count=-1 then
DMA1_Channel4.CNDTR := High(Data)+1
else
DMA1_Channel4.CNDTR := Count;
DMA1_Channel4.CPAR := LongWord(@Usart1.DR);
DMA1_Channel4.CMAR := LongWord(@Data);
DMA1_Channel4.CCR := DMA1_Channel4.CCR or %1; //enable
end;
procedure USART3_SendBytesViaDMA(var Data : array of byte; const count : integer = -1);
begin
//Disable DMA, Transfer Complete IRQ Read from Memory No Circular Mode No Periph Inc Memory Inc 8bit periph 8bit mem prio0
DMA1_Channel2.CCR := %000000010010010;
if count=-1 then
DMA1_Channel2.CNDTR := High(Data)+1
else
DMA1_Channel2.CNDTR := Count;
DMA1_Channel2.CPAR := LongWord(@Usart3.DR);
DMA1_Channel2.CMAR := LongWord(@Data);
DMA1_Channel2.CCR := DMA1_Channel2.CCR or %1; //enable
end;
begin
//************************************************
//**************** RCC *************************
//FLASH_SetLatency(1);
RCC_HSICmd(Enabled);
RCC_DeInit;
RCC_HSICmd(Enabled);
//For simplicity run on 8MHz internal Clock
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2); //24MHz
RCC_PCLK2Config(RCC_HCLK_Div1); //48MHz
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1 or RCC_AHBPeriph_SRAM or RCC_AHBPeriph_FLITF, Enabled);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ALL, Enabled);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_ALL, Enabled);
RCC_GetClocksFreq(RCC_Clocks);
GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_9; //TX USART1
GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
GPIO_Init(PortA, GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_10; //TX USART3
GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
GPIO_Init(PortB, GPIO_InitStruct);
//************************************************
//**************** USART *************************
Usart_ini.USART_BaudRate:= 9600;
Usart_ini.USART_WordLength:= USART_WordLength_8b;
Usart_ini.USART_StopBits:= USART_StopBits_1;
Usart_ini.USART_Parity:= USART_Parity_No;
Usart_ini.USART_Mode:= USART_Mode_Tx;
Usart_ini.USART_HardwareFlowControl:= USART_HardwareFlowControl_None;
Usart_ini.USART_Clock:= USART_Clock_Disable;
Usart_ini.USART_CPOL:= USART_CPOL_Low;
Usart_ini.USART_CPHA:= USART_CPHA_1Edge;
Usart_ini.USART_LastBit:= USART_LastBit_Disable;
USART_Init(USart1, Usart_ini);
USART_Init(USart3, Usart_ini);
USART_DMACmd(Usart1,USART_DMAReq_Tx,Enabled);
USART_DMACmd(Usart3,USART_DMAReq_Tx,Enabled);
Usart_Cmd(Usart1, ENABLED);
Usart_Cmd(Usart3, ENABLED);
//************************************************
//**************** NVIC **************************
NVIC_Ini.NVIC_IRQChannelPreemptionPriority:= 0;
NVIC_Ini.NVIC_IRQChannelSubPriority:= 0;
NVIC_Ini.NVIC_IRQChannel:= DMAChannel2_IRQChannel;
NVIC_Init(NVIC_Ini);
NVIC_Ini.NVIC_IRQChannel:= DMAChannel4_IRQChannel;
NVIC_Init(NVIC_Ini);
NVIC_Ini.NVIC_IRQChannelCmd := Enabled;
TXBuffer1[0] := byte('h');
TXBuffer1[1] := byte('o');
TXBuffer1[2] := byte('l');
TXBuffer1[3] := byte('a');
TXBuffer1[4] := byte('1');
TXBuffer1[5] := byte(#13);
TXBuffer1[6] := byte(#10);
TXBuffer3[0] := byte('h');
TXBuffer3[1] := byte('o');
TXBuffer3[2] := byte('l');
TXBuffer3[3] := byte('a');
TXBuffer3[4] := byte('3');
TXBuffer3[5] := byte(#13);
TXBuffer3[6] := byte(#10);
while true do
begin
USART1_SendBytesViaDMA(TXBuffer1);
USART3_SendBytesViaDMA(TXBuffer3);
//Quick hack, wait for tramsfer done....
repeat
until (DMA1_Channel2.CNDTR = 0) AND (DMA1_Channel4.CNDTR = 0);
//now waste some time so that we better see when transfer starts again
for i := 1 to 100000 do
;
end;
end.