diff --git a/include/dynamixel_master_uart.h b/include/dynamixel_master_uart_dma.h similarity index 100% rename from include/dynamixel_master_uart.h rename to include/dynamixel_master_uart_dma.h diff --git a/include/dynamixel_slave_spi.h b/include/dynamixel_slave_spi.h index 81d505a04fdebb06a87baf30a351413b375863de..cbf764a92eb7b8cfbf6e296f30f45c366adf8283 100644 --- a/include/dynamixel_slave_spi.h +++ b/include/dynamixel_slave_spi.h @@ -1,6 +1,9 @@ #ifndef _DYNAMIXEL_SLAVE_SPI_H #define _DYNAMIXEL_SLAVE_SPI_H +#include "stm32f4xx.h" +#include "dynamixel.h" + // public functions void dyn_slave_init(void); void dyn_slave_set_address(uint8_t id); diff --git a/include/dynamixel_slave_uart_dma.h b/include/dynamixel_slave_uart_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..706ca3b4bfca758e666044a5834adbc81f2757ee --- /dev/null +++ b/include/dynamixel_slave_uart_dma.h @@ -0,0 +1,16 @@ +#ifndef _DYNAMIXEL_SLAVE_UART_DMA_H +#define _DYNAXIXEL_SLAVE_UART_DMA_H + +#include "dynamixel.h" +#include "stm32f4xx.h" + +// public functions +void dyn_slave_init(void); +void dyn_slave_set_address(uint8_t id); +uint8_t dyn_slave_get_address(void); +uint8_t dyn_slave_is_packet_ready(void); +void dyn_slave_get_inst_packet(uint8_t *packet); +void dyn_slave_send_status_packet(uint8_t error,uint8_t length, uint8_t *data); +void dyn_slave_resend_status_packet(uint8_t *packet); + +#endif diff --git a/src/bioloid_stm32.c b/src/bioloid_stm32.c index 702a1d02d548e8272fd2b5114d4e5b544778749d..0c268d7020b3d13527d633aae1335c29066d8166 100644 --- a/src/bioloid_stm32.c +++ b/src/bioloid_stm32.c @@ -3,8 +3,8 @@ #include "time.h" #include "dynamixel.h" -#include "dynamixel_master_uart.h" -#include "dynamixel_slave_spi.h" +#include "dynamixel_master_uart_dma.h" +#include "dynamixel_slave_uart_dma.h" #include "eeprom.h" #include "imu_9dof_dma.h" #include "gpio.h" @@ -30,11 +30,6 @@ uint8_t read_operation(uint8_t address, uint8_t length, uint8_t *data) } } -void test_led(void) -{ - gpio_toggle_led(NORTH_LED); -} - int32_t main(void) { uint8_t inst_packet[1024]; diff --git a/src/dynamixel_master_uart_dma.c b/src/dynamixel_master_uart_dma.c index 83c88c7c8a094c54668465565f081681873ceb39..d00178c78760f4c943e02e2d92fad74b6cd1a3ce 100755 --- a/src/dynamixel_master_uart_dma.c +++ b/src/dynamixel_master_uart_dma.c @@ -1,4 +1,4 @@ -#include "dynamixel_master_uart.h" +#include "dynamixel_master_uart_dma.h" #include "time.h" #define USART USART2 diff --git a/src/dynamixel_slave_spi.c b/src/dynamixel_slave_spi.c deleted file mode 100644 index ca551a3cb3cf215e3170d2893e8587ad94ba95e7..0000000000000000000000000000000000000000 --- a/src/dynamixel_slave_spi.c +++ /dev/null @@ -1,252 +0,0 @@ -#include "stm32f4xx.h" -#include "system_stm32f4xx.h" -#include "dynamixel.h" -#include "dynamixel_slave_spi.h" - -#define SPI SPI1 -#define SPI_CLK RCC_APB2Periph_SPI1 -#define SPI_CLK_INIT RCC_APB2PeriphClockCmd -#define SPI_IRQn SPI1_IRQn -#define SPI_IRQHANDLER SPI1_IRQHandler - -#define SPI_SCK_PIN GPIO_Pin_5 -#define SPI_SCK_GPIO_PORT GPIOA -#define SPI_SCK_GPIO_CLK RCC_AHB1Periph_GPIOA -#define SPI_SCK_SOURCE GPIO_PinSource5 -#define SPI_SCK_AF GPIO_AF_SPI1 - -#define SPI_MISO_PIN GPIO_Pin_6 -#define SPI_MISO_GPIO_PORT GPIOA -#define SPI_MISO_GPIO_CLK RCC_AHB1Periph_GPIOA -#define SPI_MISO_SOURCE GPIO_PinSource6 -#define SPI_MISO_AF GPIO_AF_SPI1 - -#define SPI_MOSI_PIN GPIO_Pin_7 -#define SPI_MOSI_GPIO_PORT GPIOA -#define SPI_MOSI_GPIO_CLK RCC_AHB1Periph_GPIOA -#define SPI_MOSI_SOURCE GPIO_PinSource7 -#define SPI_MOSI_AF GPIO_AF_SPI1 - -#define SPI_NSS_PIN GPIO_Pin_4 -#define SPI_NSS_GPIO_PORT GPIOA -#define SPI_NSS_GPIO_CLK RCC_AHB1Periph_GPIOA -#define SPI_NSS_SOURCE GPIO_PinSource4 -#define SPI_NSS_AF GPIO_AF_SPI1 - -#define MAX_BUFFER_LEN 1024 - -// private varibales -uint8_t dyn_slave_address;// this module slave address -// input buffer -uint8_t dyn_slave_rx_buffer[MAX_BUFFER_LEN]; -uint16_t dyn_slave_rx_num_data; -// output buffer -uint8_t dyn_slave_tx_buffer[MAX_BUFFER_LEN]; -uint16_t dyn_slave_tx_num_data; -uint16_t dyn_slave_tx_ptr; -// instruction packet ready flag -volatile uint8_t dyn_slave_packet_ready; -// sending status packet flag -volatile uint8_t dyn_slave_sending_packet; - -// private functions -void dyn_parse_inst_packet(void) -{ - if(dyn_slave_rx_num_data>3)// the length byte has been received - { - if(dyn_slave_rx_num_data==(dyn_get_length(dyn_slave_rx_buffer)+4))// payload size plus header size - { - dyn_slave_packet_ready=0x01; - } - } -} - -void dyn_slave_set_rx_mode(void) -{ - /* Disable the Tx empty interrupt */ - SPI_I2S_ITConfig(SPI, SPI_I2S_IT_TXE, DISABLE); - /* Enable the Rx buffer not empty interrupt */ - SPI_I2S_ITConfig(SPI, SPI_I2S_IT_RXNE, ENABLE); -} - -void dyn_slave_set_tx_mode(void) -{ - /* Disable the Rx buffer not empty interrupt */ - SPI_I2S_ITConfig(SPI, SPI_I2S_IT_RXNE, DISABLE); - /* Enable the Tx empty interrupt */ - SPI_I2S_ITConfig(SPI, SPI_I2S_IT_TXE, ENABLE); -} - -// interrupt handlers -void SPI_IRQHANDLER(void) -{ - /* SPI in Receiver mode */ - if (SPI_I2S_GetITStatus(SPI, SPI_I2S_IT_RXNE) == SET) - { - if(dyn_slave_sending_packet==0x00) - { - GPIO_ToggleBits(GPIOD, GPIO_Pin_12); - dyn_slave_rx_buffer[dyn_slave_rx_num_data++] = SPI_I2S_ReceiveData(SPI); - dyn_parse_inst_packet(); - } - else - SPI_I2S_ReceiveData(SPI); - } - /* SPI in Tramitter mode */ - if (SPI_I2S_GetITStatus(SPI, SPI_I2S_IT_TXE) == SET) - { - if(dyn_slave_sending_packet==0x01) - { - if(dyn_slave_tx_num_data==0x00)// there is no more data to be sent - { - dyn_slave_tx_ptr=0x00; - dyn_slave_sending_packet=0x00; - // disable interrupts - dyn_slave_set_rx_mode(); - SPI_I2S_ReceiveData(SPI); - } - else - { - SPI_I2S_SendData(SPI,dyn_slave_tx_buffer[dyn_slave_tx_ptr++]);// send the next_byte - dyn_slave_tx_num_data--; - } - } - } -} - -// public functions -void dyn_slave_init(void) -{ - uint16_t i; - GPIO_InitTypeDef GPIO_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; - SPI_InitTypeDef SPI_InitStructure; - - // initialize the buffers - for(i=0;i<MAX_BUFFER_LEN;i++) - { - dyn_slave_rx_buffer[i]=0x00; - dyn_slave_tx_buffer[i]=0x00; - } - dyn_slave_rx_num_data=0x00; - dyn_slave_tx_num_data=0x00; - dyn_slave_tx_ptr=0x00; - // initialize the flags - dyn_slave_packet_ready=0x00; - dyn_slave_sending_packet=0x00; - - /* Enable the SPI clock */ - SPI_CLK_INIT(SPI_CLK, ENABLE); - - /* Enable GPIO clocks */ - RCC_AHB1PeriphClockCmd(SPI_SCK_GPIO_CLK | SPI_MISO_GPIO_CLK | SPI_MOSI_GPIO_CLK | SPI_NSS_GPIO_CLK, ENABLE); - - /* SPI GPIO Configuration --------------------------------------------------*/ - - /* Connect SPI pins to AF5 */ - GPIO_PinAFConfig(SPI_SCK_GPIO_PORT, SPI_SCK_SOURCE, SPI_SCK_AF); - GPIO_PinAFConfig(SPI_MISO_GPIO_PORT, SPI_MISO_SOURCE, SPI_MISO_AF); - GPIO_PinAFConfig(SPI_MOSI_GPIO_PORT, SPI_MOSI_SOURCE, SPI_MOSI_AF); - GPIO_PinAFConfig(SPI_NSS_GPIO_PORT, SPI_NSS_SOURCE, SPI_NSS_AF); - - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; - - /* SPI SCK pin configuration */ - GPIO_InitStructure.GPIO_Pin = SPI_SCK_PIN; - GPIO_Init(SPI_SCK_GPIO_PORT, &GPIO_InitStructure); - - /* SPI MISO pin configuration */ - GPIO_InitStructure.GPIO_Pin = SPI_MISO_PIN; - GPIO_Init(SPI_MISO_GPIO_PORT, &GPIO_InitStructure); - - /* SPI MOSI pin configuration */ - GPIO_InitStructure.GPIO_Pin = SPI_MOSI_PIN; - GPIO_Init(SPI_MOSI_GPIO_PORT, &GPIO_InitStructure); - - /* SPI NSS pin configuration */ - GPIO_InitStructure.GPIO_Pin = SPI_NSS_PIN; - GPIO_Init(SPI_NSS_GPIO_PORT, &GPIO_InitStructure); - - /* SPI configuration -------------------------------------------------------*/ - SPI_I2S_DeInit(SPI); - SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; - SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; - SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; - SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; - SPI_InitStructure.SPI_NSS = SPI_NSS_Hard; - SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; - SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; - SPI_InitStructure.SPI_CRCPolynomial = 7; - SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; - SPI_Init(SPI, &SPI_InitStructure); - - /* Configure the SPI interrupt priority */ - NVIC_InitStructure.NVIC_IRQChannel = SPI_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - - /* by default set receive mode */ - dyn_slave_set_rx_mode(); - - /* Enable the SPI peripheral */ - SPI_Cmd(SPI, ENABLE); -} - -void dyn_slave_set_address(uint8_t id) -{ - dyn_slave_address=id; -} - -uint8_t dyn_slave_get_address(void) -{ - return dyn_slave_address; -} - -uint8_t dyn_slave_is_packet_ready(void) -{ - return dyn_slave_packet_ready; -} - -void dyn_slave_get_inst_packet(uint8_t *packet) -{ - uint8_t i; - - for(i=0;i<dyn_slave_rx_num_data;i++) - packet[i]=dyn_slave_rx_buffer[i]; - dyn_slave_rx_num_data=0x00; - dyn_slave_packet_ready=0x00; -} - -void dyn_slave_send_status_packet(uint8_t error,uint8_t length, uint8_t *data) -{ - // wait until the previous transmission has ended (if any) - while(dyn_slave_sending_packet==0x01); - // create the status packet - dyn_init_status_packet(dyn_slave_tx_buffer); - dyn_set_status_error(dyn_slave_tx_buffer,error); - dyn_set_id(dyn_slave_tx_buffer,dyn_slave_address); - dyn_set_status_data(dyn_slave_tx_buffer,length,data); - dyn_set_checksum(dyn_slave_tx_buffer); - // start sending the package - dyn_slave_tx_num_data=dyn_get_length(dyn_slave_tx_buffer)+4+1; - dyn_slave_sending_packet=0x01; - dyn_slave_set_tx_mode(); -} - -void dyn_slave_resend_status_packet(uint8_t *packet) -{ - // wait until the previous transmission has ended (if any) - while(dyn_slave_sending_packet==0x01); - // create the status packet - dyn_init_status_packet(dyn_slave_tx_buffer); - dyn_copy_packet(packet,dyn_slave_tx_buffer); - // start sending the package - dyn_slave_tx_num_data=dyn_get_length(dyn_slave_tx_buffer)+4+1; - dyn_slave_sending_packet=0x01; - dyn_slave_set_tx_mode(); -} diff --git a/src/dynamixel_slave_uart_dma.c b/src/dynamixel_slave_uart_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..8b981fd6cc025d2d565d429ee2cd0f13649f4e5b --- /dev/null +++ b/src/dynamixel_slave_uart_dma.c @@ -0,0 +1,290 @@ +#include "dynamixel_slave_uart_dma.h" + +#define DYN_SLAVE USART3 +#define DYN_SLAVE_CLK RCC_APB1Periph_USART3 +#define DYN_SLAVE_CLK_INIT RCC_APB1PeriphClockCmd +#define DYN_SLAVE_IRQn USART3_IRQn +#define DYN_SLAVE_IRQHandler USART3_IRQHandler + +#define DYN_SLAVE_TX_PIN GPIO_Pin_10 +#define DYN_SLAVE_TX_GPIO_PORT GPIOC +#define DYN_SLAVE_TX_GPIO_CLK RCC_AHB1Periph_GPIOC +#define DYN_SLAVE_TX_SOURCE GPIO_PinSource10 +#define DYN_SLAVE_TX_AF GPIO_AF_USART3 + +#define DYN_SLAVE_RX_PIN GPIO_Pin_11 +#define DYN_SLAVE_RX_GPIO_PORT GPIOC +#define DYN_SLAVE_RX_GPIO_CLK RCC_AHB1Periph_GPIOB +#define DYN_SLAVE_RX_SOURCE GPIO_PinSource11 +#define DYN_SLAVE_RX_AF GPIO_AF_USART3 + +/* DMA configuration */ +#define DYN_SLAVE_DR_ADDRESS ((uint32_t)USART3 + 0x04) +#define DYN_SLAVE_DMA DMA1 +#define DYN_SLAVE_DMA_CLK RCC_AHB1Periph_DMA1 + +#define DYN_SLAVE_TX_DMA_CHANNEL DMA_Channel_4 +#define DYN_SLAVE_TX_DMA_STREAM DMA1_Stream3 +#define DYN_SLAVE_TX_DMA_FLAG_FEIF DMA_FLAG_FEIF3 +#define DYN_SLAVE_TX_DMA_FLAG_DMEIF DMA_FLAG_DMEIF3 +#define DYN_SLAVE_TX_DMA_FLAG_TEIF DMA_FLAG_TEIF3 +#define DYN_SLAVE_TX_DMA_FLAG_HTIF DMA_FLAG_HTIF3 +#define DYN_SLAVE_TX_DMA_FLAG_TCIF DMA_FLAG_TCIF3 + +#define DYN_SLAVE_RX_DMA_CHANNEL DMA_Channel_4 +#define DYN_SLAVE_RX_DMA_STREAM DMA1_Stream1 +#define DYN_SLAVE_RX_DMA_FLAG_FEIF DMA_FLAG_FEIF1 +#define DYN_SLAVE_RX_DMA_FLAG_DMEIF DMA_FLAG_DMEIF1 +#define DYN_SLAVE_RX_DMA_FLAG_TEIF DMA_FLAG_TEIF1 +#define DYN_SLAVE_RX_DMA_FLAG_HTIF DMA_FLAG_HTIF1 +#define DYN_SLAVE_RX_DMA_FLAG_TCIF DMA_FLAG_TCIF1 + +#define DYN_SLAVE_DMA_TX_IRQn DMA1_Stream3_IRQn +#define DYN_SLAVE_DMA_RX_IRQn DMA1_Stream1_IRQn +#define DYN_SLAVE_DMA_TX_IRQHandler DMA1_Stream3_IRQHandler +#define DYN_SLAVE_DMA_RX_IRQHandler DMA1_Stream1_IRQHandler + +#define MAX_BUFFER_LEN 1024 + +// private variables +uint8_t dyn_slave_address;// this module slave address +// input buffer +uint8_t dyn_slave_rx_buffer[MAX_BUFFER_LEN]; +volatile uint8_t dyn_slave_receiving_header; +// output buffer +uint8_t dyn_slave_tx_buffer[MAX_BUFFER_LEN]; +// instruction packet ready flag +volatile uint8_t dyn_slave_packet_ready; +// sending status packet flag +volatile uint8_t dyn_slave_sending_packet; +// DMA initialization data structures +DMA_InitTypeDef DYN_SLAVE_DMA_TX_InitStructure; +DMA_InitTypeDef DYN_SLAVE_DMA_RX_InitStructure; + +// private functions + +// interrupt handlers +void DYN_SLAVE_IRQHandler(void) +{ + if(USART_GetITStatus(DYN_SLAVE, USART_IT_TC) != RESET) + { + USART_ClearFlag(DYN_SLAVE,USART_FLAG_TC); + USART_ITConfig(DYN_SLAVE, USART_IT_TC, DISABLE); + dyn_slave_sending_packet=0x00; + // set up the DMA RX transaction + DYN_SLAVE_DMA_RX_InitStructure.DMA_BufferSize = 4; + DYN_SLAVE_DMA_RX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dyn_slave_rx_buffer; + DMA_Init(DYN_SLAVE_RX_DMA_STREAM,&DYN_SLAVE_DMA_RX_InitStructure); + DMA_ITConfig(DYN_SLAVE_RX_DMA_STREAM,DMA_IT_TC,ENABLE); + DMA_Cmd(DYN_SLAVE_RX_DMA_STREAM,ENABLE); + USART_DMACmd(DYN_SLAVE, USART_DMAReq_Rx, ENABLE); + dyn_slave_receiving_header=0x01; + } +} + +void DYN_SLAVE_DMA_TX_IRQHandler(void) +{ + DMA_ClearFlag(DYN_SLAVE_TX_DMA_STREAM,DYN_SLAVE_TX_DMA_FLAG_TCIF); + DMA_ClearITPendingBit(DYN_SLAVE_TX_DMA_STREAM,DYN_SLAVE_TX_DMA_FLAG_TCIF); + USART_ITConfig(DYN_SLAVE, USART_IT_TC, ENABLE); +} + +void DYN_SLAVE_DMA_RX_IRQHandler(void) +{ + if(dyn_slave_receiving_header==0x01) + { + DMA_ClearFlag(DYN_SLAVE_RX_DMA_STREAM,DYN_SLAVE_RX_DMA_FLAG_TCIF); + DMA_ClearITPendingBit(DYN_SLAVE_RX_DMA_STREAM,DYN_SLAVE_RX_DMA_FLAG_TCIF); + DYN_SLAVE_DMA_RX_InitStructure.DMA_BufferSize = dyn_get_length(dyn_slave_rx_buffer); + DYN_SLAVE_DMA_RX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&dyn_slave_rx_buffer[4]; + DMA_Init(DYN_SLAVE_RX_DMA_STREAM,&DYN_SLAVE_DMA_RX_InitStructure); + DMA_Cmd(DYN_SLAVE_RX_DMA_STREAM,ENABLE); + USART_DMACmd(DYN_SLAVE, USART_DMAReq_Rx, ENABLE); + dyn_slave_receiving_header=0x00; + } + else + { + DMA_ClearFlag(DYN_SLAVE_RX_DMA_STREAM,DYN_SLAVE_RX_DMA_FLAG_TCIF); + DMA_ClearITPendingBit(DYN_SLAVE_RX_DMA_STREAM,DYN_SLAVE_RX_DMA_FLAG_TCIF); + DMA_ITConfig(DYN_SLAVE_RX_DMA_STREAM,DMA_IT_TC,DISABLE); + dyn_slave_packet_ready=0x01; + } +} + +// public functions +void dyn_slave_init(void) +{ + uint16_t i; + GPIO_InitTypeDef GPIO_InitStructure; + NVIC_InitTypeDef NVIC_InitStructure; + USART_InitTypeDef USART_InitStructure; + + /* Enable GPIO clock */ + DYN_SLAVE_CLK_INIT(DYN_SLAVE_CLK, ENABLE); + RCC_AHB1PeriphClockCmd(DYN_SLAVE_TX_GPIO_CLK | DYN_SLAVE_RX_GPIO_CLK, ENABLE); + // configure the GPIO pins + + /* Connect USART pins to AF7 */ + GPIO_PinAFConfig(DYN_SLAVE_TX_GPIO_PORT, DYN_SLAVE_TX_SOURCE, DYN_SLAVE_TX_AF); + GPIO_PinAFConfig(DYN_SLAVE_RX_GPIO_PORT, DYN_SLAVE_RX_SOURCE, DYN_SLAVE_RX_AF); + + /* Configure USART Tx and Rx as alternate function push-pull */ + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Pin = DYN_SLAVE_TX_PIN; + GPIO_Init(DYN_SLAVE_TX_GPIO_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = DYN_SLAVE_RX_PIN; + GPIO_Init(DYN_SLAVE_RX_GPIO_PORT, &GPIO_InitStructure); + + // initialize the buffers + for(i=0;i<MAX_BUFFER_LEN;i++) + { + dyn_slave_rx_buffer[i]=0x00; + dyn_slave_tx_buffer[i]=0x00; + } + // initialize the flags + dyn_slave_packet_ready=0x00; + dyn_slave_sending_packet=0x00; + dyn_slave_receiving_header=0x01; + + USART_DeInit(DYN_SLAVE); + USART_StructInit(&USART_InitStructure); + // configure the serial port + USART_InitStructure.USART_BaudRate = 115200; + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_Parity = USART_Parity_No; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + USART_Init(DYN_SLAVE, &USART_InitStructure); + + NVIC_InitStructure.NVIC_IRQChannel = DYN_SLAVE_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + USART_ITConfig(DYN_SLAVE, USART_IT_RXNE | USART_IT_ORE | USART_IT_TXE | USART_IT_CTS | USART_IT_LBD | USART_IT_IDLE | USART_IT_PE | USART_IT_ERR | USART_IT_TC, DISABLE); + USART_ClearFlag(DYN_SLAVE,USART_FLAG_RXNE | USART_FLAG_ORE | USART_FLAG_TXE | USART_FLAG_CTS | USART_FLAG_LBD | USART_FLAG_IDLE | USART_FLAG_PE | USART_FLAG_TC); + USART_ClearITPendingBit(DYN_SLAVE, USART_FLAG_RXNE | USART_FLAG_ORE | USART_FLAG_TXE | USART_FLAG_CTS | USART_FLAG_LBD | USART_FLAG_IDLE | USART_FLAG_PE | USART_FLAG_TC); + /* Enable the DYN_SLAVE3 */ + USART_Cmd(DYN_SLAVE, ENABLE); + + // configure the DMA channels + /* Configure TX DMA */ + RCC_AHB1PeriphClockCmd(DYN_SLAVE_DMA_CLK, ENABLE); + DMA_DeInit(DYN_SLAVE_TX_DMA_STREAM); + DYN_SLAVE_DMA_TX_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DYN_SLAVE_DMA_TX_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; + DYN_SLAVE_DMA_TX_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DYN_SLAVE_DMA_TX_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DYN_SLAVE_DMA_TX_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DYN_SLAVE_DMA_TX_InitStructure.DMA_Mode = DMA_Mode_Normal; + DYN_SLAVE_DMA_TX_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(DYN_SLAVE->DR)); + DYN_SLAVE_DMA_TX_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DYN_SLAVE_DMA_TX_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DYN_SLAVE_DMA_TX_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DYN_SLAVE_DMA_TX_InitStructure.DMA_Priority = DMA_Priority_High; + DYN_SLAVE_DMA_TX_InitStructure.DMA_Channel = DYN_SLAVE_TX_DMA_CHANNEL; + DYN_SLAVE_DMA_TX_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + DYN_SLAVE_DMA_TX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dyn_slave_tx_buffer; + DMA_Init(DYN_SLAVE_TX_DMA_STREAM,&DYN_SLAVE_DMA_TX_InitStructure); + /* initialize DMA interrupts */ + NVIC_InitStructure.NVIC_IRQChannel = DYN_SLAVE_DMA_TX_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + DMA_ITConfig(DYN_SLAVE_TX_DMA_STREAM,DMA_IT_TC,ENABLE); + DMA_ITConfig(DYN_SLAVE_TX_DMA_STREAM,DMA_IT_HT | DMA_IT_TE | DMA_IT_FE | DMA_IT_DME,DISABLE); + + /* Configure RX DMA */ + DMA_DeInit(DYN_SLAVE_RX_DMA_STREAM); + DYN_SLAVE_DMA_RX_InitStructure.DMA_BufferSize = 4;// transfer the first 3 bytes + DYN_SLAVE_DMA_RX_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DYN_SLAVE_DMA_RX_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; + DYN_SLAVE_DMA_RX_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DYN_SLAVE_DMA_RX_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DYN_SLAVE_DMA_RX_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DYN_SLAVE_DMA_RX_InitStructure.DMA_Mode = DMA_Mode_Normal; + DYN_SLAVE_DMA_RX_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (&(DYN_SLAVE->DR)); + DYN_SLAVE_DMA_RX_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DYN_SLAVE_DMA_RX_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DYN_SLAVE_DMA_RX_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DYN_SLAVE_DMA_RX_InitStructure.DMA_Priority = DMA_Priority_High; + DYN_SLAVE_DMA_RX_InitStructure.DMA_Channel = DYN_SLAVE_RX_DMA_CHANNEL; + DYN_SLAVE_DMA_RX_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DYN_SLAVE_DMA_RX_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dyn_slave_rx_buffer; + DMA_Init(DYN_SLAVE_RX_DMA_STREAM,&DYN_SLAVE_DMA_RX_InitStructure); + /* initialize DMA interrupts */ + NVIC_InitStructure.NVIC_IRQChannel = DYN_SLAVE_DMA_RX_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + DMA_ITConfig(DYN_SLAVE_RX_DMA_STREAM,DMA_IT_TC,ENABLE); + DMA_ITConfig(DYN_SLAVE_RX_DMA_STREAM,DMA_IT_HT | DMA_IT_TE | DMA_IT_FE | DMA_IT_DME,DISABLE); + + DMA_Cmd(DYN_SLAVE_RX_DMA_STREAM,ENABLE); + USART_DMACmd(DYN_SLAVE, USART_DMAReq_Rx, ENABLE); +} + +void dyn_slave_set_address(uint8_t id) +{ + dyn_slave_address=id; +} + +uint8_t dyn_slave_get_address(void) +{ + return dyn_slave_address; +} + +uint8_t dyn_slave_is_packet_ready(void) +{ + return dyn_slave_packet_ready; +} + +void dyn_slave_get_inst_packet(uint8_t *packet) +{ + uint8_t i; + + for(i=0;i<dyn_get_length(dyn_slave_rx_buffer)+4;i++) + packet[i]=dyn_slave_rx_buffer[i]; + dyn_slave_packet_ready=0x00; +} + +void dyn_slave_send_status_packet(uint8_t error,uint8_t length, uint8_t *data) +{ + // wait until the previous transmission has ended (if any) + while(dyn_slave_sending_packet==0x01); + // create the status packet + dyn_init_status_packet(dyn_slave_tx_buffer); + dyn_set_status_error(dyn_slave_tx_buffer,error); + dyn_set_id(dyn_slave_tx_buffer,dyn_slave_address); + dyn_set_status_data(dyn_slave_tx_buffer,length,data); + dyn_set_checksum(dyn_slave_tx_buffer); + // set the DMA transfer + DMA_SetCurrDataCounter(DYN_SLAVE_TX_DMA_STREAM,dyn_get_length(dyn_slave_tx_buffer)+4); + DMA_Cmd(DYN_SLAVE_TX_DMA_STREAM,ENABLE); + USART_ClearFlag(DYN_SLAVE,USART_FLAG_TC); + USART_DMACmd(DYN_SLAVE, USART_DMAReq_Tx, ENABLE); + dyn_slave_sending_packet=0x01; +} + +void dyn_slave_resend_status_packet(uint8_t *packet) +{ + // wait until the previous transmission has ended (if any) + while(dyn_slave_sending_packet==0x01); + // create the status packet + dyn_init_status_packet(dyn_slave_tx_buffer); + dyn_copy_packet(packet,dyn_slave_tx_buffer); + // set the DMA transfer + DMA_SetCurrDataCounter(DYN_SLAVE_TX_DMA_STREAM,dyn_get_length(dyn_slave_tx_buffer)+4); + DMA_Cmd(DYN_SLAVE_TX_DMA_STREAM,ENABLE); + USART_ClearFlag(DYN_SLAVE,USART_FLAG_TC); + USART_DMACmd(DYN_SLAVE, USART_DMAReq_Tx, ENABLE); + dyn_slave_sending_packet=0x01; +}