From 224043be4e0a201733b8369231949c1fe7e79ca3 Mon Sep 17 00:00:00 2001 From: Evgeny Sychov Date: Mon, 27 Jun 2016 10:55:41 -0700 Subject: [PATCH 1/6] MAX7456 driver - add support for SPI DMA --- src/main/drivers/bus_spi.c | 3 +- src/main/drivers/max7456.c | 208 ++++++++++++++++++---------- src/main/drivers/max7456.h | 12 +- src/main/drivers/nvic.h | 1 + src/main/io/osd.c | 217 ++++++++++++++++++++---------- src/main/target/SIRINFPV/target.h | 7 + 6 files changed, 301 insertions(+), 147 deletions(-) diff --git a/src/main/drivers/bus_spi.c b/src/main/drivers/bus_spi.c index 5af40d0750..c4d53145cc 100644 --- a/src/main/drivers/bus_spi.c +++ b/src/main/drivers/bus_spi.c @@ -358,4 +358,5 @@ void spiResetErrorCounter(SPI_TypeDef *instance) SPIDevice device = spiDeviceByInstance(instance); if (device != SPIINVALID) spiHardwareMap[device].errorCount = 0; -} \ No newline at end of file +} + diff --git a/src/main/drivers/max7456.c b/src/main/drivers/max7456.c index b8a59bcfc9..fa2fbc245e 100644 --- a/src/main/drivers/max7456.c +++ b/src/main/drivers/max7456.c @@ -29,6 +29,7 @@ #include "drivers/bus_spi.h" #include "drivers/light_led.h" #include "drivers/system.h" +#include "drivers/nvic.h" #include "max7456.h" #include "max7456_symbols.h" @@ -36,30 +37,120 @@ #define DISABLE_MAX7456 IOHi(max7456CsPin) #define ENABLE_MAX7456 IOLo(max7456CsPin) -/** Artificial Horizon limits **/ -#define AHIPITCHMAX 200 // Specify maximum AHI pitch value displayed. Default 200 = 20.0 degrees -#define AHIROLLMAX 400 // Specify maximum AHI roll value displayed. Default 400 = 40.0 degrees -#define AHISIDEBARWIDTHPOSITION 7 -#define AHISIDEBARHEIGHTPOSITION 3 - uint16_t max_screen_size; -char max7456_screen[VIDEO_BUFFER_CHARS_PAL]; +static MAX7456_CHAR_TYPE max7456_screen[VIDEO_BUFFER_CHARS_PAL + 5]; +#define SCREEN_BUFFER ((MAX7456_CHAR_TYPE*)&max7456_screen[3]) + +#ifdef MAX7456_DMA_CHANNEL_TX +volatile uint8_t dma_transaction_in_progress = 0; +#endif static uint8_t video_signal_type = 0; static uint8_t max7456_lock = 0; static IO_t max7456CsPin = IO_NONE; -uint8_t max7456_send(uint8_t add, uint8_t data) { + +MAX7456_CHAR_TYPE* max7456_get_screen_buffer(void) { + return SCREEN_BUFFER; +} + +static uint8_t max7456_send(uint8_t add, uint8_t data) { spiTransferByte(MAX7456_SPI_INSTANCE, add); return spiTransferByte(MAX7456_SPI_INSTANCE, data); } +#ifdef MAX7456_DMA_CHANNEL_TX +static void max7456_send_dma(void* tx_buffer, void* rx_buffer, uint16_t buffer_size) { + DMA_InitTypeDef DMA_InitStructure; +#ifdef MAX7456_DMA_CHANNEL_RX + static uint16_t dummy[] = {0xffff}; +#else + UNUSED(rx_buffer); +#endif + while (dma_transaction_in_progress); // Wait for prev DMA transaction + + DMA_DeInit(MAX7456_DMA_CHANNEL_TX); +#ifdef MAX7456_DMA_CHANNEL_RX + DMA_DeInit(MAX7456_DMA_CHANNEL_RX); +#endif + + // Common to both channels + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(MAX7456_SPI_INSTANCE->DR)); + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_BufferSize = buffer_size; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_Low; + DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; + +#ifdef MAX7456_DMA_CHANNEL_RX + // Rx Channel + DMA_InitStructure.DMA_MemoryBaseAddr = rx_buffer ? (uint32_t)rx_buffer : (uint32_t)(dummy); + DMA_InitStructure.DMA_MemoryInc = rx_buffer ? DMA_MemoryInc_Enable : DMA_MemoryInc_Disable; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; + + DMA_Init(MAX7456_DMA_CHANNEL_RX, &DMA_InitStructure); + DMA_Cmd(MAX7456_DMA_CHANNEL_RX, ENABLE); +#endif + // Tx channel + + DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)tx_buffer; //max7456_screen; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; + + DMA_Init(MAX7456_DMA_CHANNEL_TX, &DMA_InitStructure); + DMA_Cmd(MAX7456_DMA_CHANNEL_TX, ENABLE); + +#ifdef MAX7456_DMA_CHANNEL_RX + DMA_ITConfig(MAX7456_DMA_CHANNEL_RX, DMA_IT_TC, ENABLE); +#else + DMA_ITConfig(MAX7456_DMA_CHANNEL_TX, DMA_IT_TC, ENABLE); +#endif + + // Enable SPI TX/RX request + ENABLE_MAX7456; + dma_transaction_in_progress = 1; + + SPI_I2S_DMACmd(MAX7456_SPI_INSTANCE, +#ifdef MAX7456_DMA_CHANNEL_RX + SPI_I2S_DMAReq_Rx | +#endif + SPI_I2S_DMAReq_Tx, ENABLE); +} + +void MAX7456_DMA_IRQ_HANDLER_FUNCTION (void) { + if (DMA_GetFlagStatus(MAX7456_DMA_TC_FLAG)) { +#ifdef MAX7456_DMA_CHANNEL_RX + DMA_Cmd(MAX7456_DMA_CHANNEL_RX, DISABLE); +#else + //Empty RX buffer. RX DMA takes care of it if enabled + while (SPI_I2S_GetFlagStatus(MAX7456_SPI_INSTANCE, SPI_I2S_FLAG_RXNE) == SET) { + MAX7456_SPI_INSTANCE->DR; + } +#endif + DMA_Cmd(MAX7456_DMA_CHANNEL_TX, DISABLE); + + DMA_ClearFlag(MAX7456_DMA_TC_FLAG); + + SPI_I2S_DMACmd(MAX7456_SPI_INSTANCE, +#ifdef MAX7456_DMA_CHANNEL_RX + SPI_I2S_DMAReq_Rx | +#endif + SPI_I2S_DMAReq_Tx, DISABLE); + + DISABLE_MAX7456; + for (uint16_t x = 0; x < max_screen_size; x++) + max7456_screen[x + 3] = MAX7456ADD_DMDI; + dma_transaction_in_progress = 0; + } +} +#endif void max7456_init(uint8_t video_system) { uint8_t max_screen_rows; uint8_t srdata = 0; uint16_t x; - char buf[LINE]; #ifdef MAX7456_SPI_CS_PIN max7456CsPin = IOGetByTag(IO_TAG(MAX7456_SPI_CS_PIN)); @@ -68,7 +159,7 @@ void max7456_init(uint8_t video_system) { IOConfigGPIO(max7456CsPin, SPI_IO_CS_CFG); //Minimum spi clock period for max7456 is 100ns (10Mhz) - spiSetDivisor(MAX7456_SPI_INSTANCE, SPI_9MHZ_CLOCK_DIVIDER); + spiSetDivisor(MAX7456_SPI_INSTANCE, SPI_STANDARD_CLOCK); delay(1000); // force soft reset on Max7456 @@ -112,94 +203,73 @@ void max7456_init(uint8_t video_system) { DISABLE_MAX7456; delay(100); + + for (x = 0; x < max_screen_size; x++) + SCREEN_BUFFER[x] = MAX7456_CHAR(0); + +#ifdef MAX7456_DMA_CHANNEL_TX + max7456_screen[0] = (uint16_t)(MAX7456ADD_DMAH | (0 << 8)); + max7456_screen[1] = (uint16_t)(MAX7456ADD_DMAL | (0 << 8)); + max7456_screen[2] = (uint16_t)(MAX7456ADD_DMM | (1 << 8)); + max7456_screen[max_screen_size + 3] = (uint16_t)(MAX7456ADD_DMDI | (0xFF << 8)); + max7456_screen[max_screen_size + 4] = (uint16_t)(MAX7456ADD_DMM | (0 << 8)); + + RCC_AHBPeriphClockCmd(MAX7456_DMA_PERIPH_CLOCK, ENABLE); + NVIC_InitTypeDef NVIC_InitStructure; + + NVIC_InitStructure.NVIC_IRQChannel = MAX7456_DMA_IRQ_HANDLER_ID; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_MAX7456_DMA); + NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_MAX7456_DMA); + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +#endif } // Copy string from ram into screen buffer void max7456_write_string(const char *string, int16_t address) { - char *dest; + MAX7456_CHAR_TYPE *dest; if (address >= 0) - dest = max7456_screen + address; + dest = SCREEN_BUFFER + address; else - dest = max7456_screen + (max_screen_size + address); + dest = SCREEN_BUFFER + (max_screen_size + address); - while(*string && dest < (max7456_screen + max_screen_size)) - *dest++ = *string++; -} - - -// Write the artifical horizon to the screen buffer -void max7456_artificial_horizon(int rollAngle, int pitchAngle, uint8_t show_sidebars) { - uint16_t position = 194; - - if(pitchAngle>AHIPITCHMAX) pitchAngle=AHIPITCHMAX; - if(pitchAngle<-AHIPITCHMAX) pitchAngle=-AHIPITCHMAX; - if(rollAngle>AHIROLLMAX) rollAngle=AHIROLLMAX; - if(rollAngle<-AHIROLLMAX) rollAngle=-AHIROLLMAX; - - for(uint8_t X=0; X<=8; X++) { - if (X==4) X=5; - int Y = (rollAngle * (4-X)) / 64; - Y -= pitchAngle / 8; - Y += 41; - if(Y >= 0 && Y <= 81) { - uint16_t pos = position -7 + LINE*(Y/9) + 3 - 4*LINE + X; - max7456_screen[pos] = SYM_AH_BAR9_0+(Y%9); - } - } - max7456_screen[position-1] = SYM_AH_CENTER_LINE; - max7456_screen[position+1] = SYM_AH_CENTER_LINE_RIGHT; - max7456_screen[position] = SYM_AH_CENTER; - - if (show_sidebars) { - // Draw AH sides - int8_t hudwidth = AHISIDEBARWIDTHPOSITION; - int8_t hudheight = AHISIDEBARHEIGHTPOSITION; - for(int8_t X=-hudheight; X<=hudheight; X++) { - max7456_screen[position-hudwidth+(X*LINE)] = SYM_AH_DECORATION; - max7456_screen[position+hudwidth+(X*LINE)] = SYM_AH_DECORATION; - } - // AH level indicators - max7456_screen[position-hudwidth+1] = SYM_AH_LEFT; - max7456_screen[position+hudwidth-1] = SYM_AH_RIGHT; + while(*string && dest < (SCREEN_BUFFER + max_screen_size)) { + *dest++ = MAX7456_CHAR(*string++); } } void max7456_draw_screen(void) { - uint16_t xx; if (!max7456_lock) { - ENABLE_MAX7456; - for (xx = 0; xx < max_screen_size; ++xx) { - max7456_send(MAX7456ADD_DMAH, xx>>8); - max7456_send(MAX7456ADD_DMAL, xx); - max7456_send(MAX7456ADD_DMDI, max7456_screen[xx]); - max7456_screen[xx] = ' '; - } - DISABLE_MAX7456; - } -} +#ifdef MAX7456_DMA_CHANNEL_TX + max7456_send_dma(max7456_screen, NULL, max_screen_size * 2 + 10); +#else + uint16_t xx; + max7456_lock = 1; -void max7456_draw_screen_fast(void) { - uint16_t xx; - if (!max7456_lock) { ENABLE_MAX7456; max7456_send(MAX7456ADD_DMAH, 0); max7456_send(MAX7456ADD_DMAL, 0); max7456_send(MAX7456ADD_DMM, 1); for (xx = 0; xx < max_screen_size; ++xx) { - max7456_send(MAX7456ADD_DMDI, max7456_screen[xx]); - max7456_screen[xx] = ' '; + max7456_send(MAX7456ADD_DMDI, SCREEN_BUFFER[xx]); + SCREEN_BUFFER[xx] = MAX7456_CHAR(0); } max7456_send(MAX7456ADD_DMDI, 0xFF); max7456_send(MAX7456ADD_DMM, 0); DISABLE_MAX7456; + max7456_lock = 0; +#endif } } - void max7456_write_nvm(uint8_t char_address, uint8_t *font_data) { uint8_t x; +#ifdef MAX7456_DMA_CHANNEL_TX + while (dma_transaction_in_progress); +#endif + while (max7456_lock); max7456_lock = 1; ENABLE_MAX7456; diff --git a/src/main/drivers/max7456.h b/src/main/drivers/max7456.h index 1e04320a88..5ba902ba5a 100644 --- a/src/main/drivers/max7456.h +++ b/src/main/drivers/max7456.h @@ -143,12 +143,18 @@ enum VIDEO_TYPES { AUTO = 0, PAL, NTSC }; extern uint16_t max_screen_size; -extern char max7456_screen[VIDEO_BUFFER_CHARS_PAL]; +#ifdef MAX7456_DMA_CHANNEL_TX + #define MAX7456_CHAR_TYPE uint16_t + #define MAX7456_CHAR(X) (MAX7456ADD_DMDI | ((X) << 8)) +#else + #define MAX7456_CHAR_TYPE char + #define MAX7456_CHAR(X) (X) +#endif void max7456_init(uint8_t system); void max7456_draw_screen(void); -void max7456_draw_screen_fast(void); -void max7456_artificial_horizon(int rollAngle, int pitchAngle, uint8_t show_sidebars); void max7456_write_string(const char *string, int16_t address); void max7456_write_nvm(uint8_t char_address, uint8_t *font_data); +MAX7456_CHAR_TYPE* max7456_get_screen_buffer(void); + diff --git a/src/main/drivers/nvic.h b/src/main/drivers/nvic.h index 7d6b100a94..e87fb6bfad 100644 --- a/src/main/drivers/nvic.h +++ b/src/main/drivers/nvic.h @@ -39,6 +39,7 @@ #define NVIC_PRIO_MAG_DATA_READY NVIC_BUILD_PRIORITY(0x0f, 0x0f) #define NVIC_PRIO_CALLBACK NVIC_BUILD_PRIORITY(0x0f, 0x0f) #define NVIC_PRIO_BST_READ_DATA NVIC_BUILD_PRIORITY(1, 1) +#define NVIC_PRIO_MAX7456_DMA NVIC_BUILD_PRIORITY(3, 0) // utility macros to join/split priority #define NVIC_BUILD_PRIORITY(base,sub) (((((base)<<(4-(7-(NVIC_PRIORITY_GROUPING>>8))))|((sub)&(0x0f>>(7-(NVIC_PRIORITY_GROUPING>>8)))))<<4)&0xf0) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index db4c8ad4e0..909ee931e0 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -122,6 +122,11 @@ #define STICKMIN 10 #define STICKMAX 90 +/** Artificial Horizon limits **/ +#define AHIPITCHMAX 200 // Specify maximum AHI pitch value displayed. Default 200 = 20.0 degrees +#define AHIROLLMAX 400 // Specify maximum AHI roll value displayed. Default 400 = 40.0 degrees +#define AHISIDEBARWIDTHPOSITION 7 +#define AHISIDEBARHEIGHTPOSITION 3 static uint32_t next_osd_update_at = 0; static uint32_t armed_seconds = 0; @@ -194,6 +199,23 @@ void print_vtx_freq(uint16_t pos, uint8_t col) { sprintf(string_buffer, "%d M", vtx_freq[current_vtx_channel]); max7456_write_string(string_buffer, pos); } + +void update_vtx_power(int value_change_direction, uint8_t col) { + UNUSED(col); + if (value_change_direction) { + masterConfig.vtx_power = 0; + } else { + masterConfig.vtx_power = 1; + } + rtc6705_soft_spi_set_rf_power(masterConfig.vtx_power); +} + +void print_vtx_power(uint16_t pos, uint8_t col) { + UNUSED(col); + sprintf(string_buffer, "%s", masterConfig.vtx_power ? "25MW" : "200MW"); + max7456_write_string(string_buffer, pos); +} + #endif void print_pid(uint16_t pos, uint8_t col, int pid_term) { @@ -400,7 +422,7 @@ osd_page_t menu_pages[] = { { .title = "VTX SETTINGS", .cols_number = 1, - .rows_number = 3, + .rows_number = 4, .cols = { { .title = NULL, @@ -422,6 +444,11 @@ osd_page_t menu_pages[] = { .title = "FREQUENCY", .update = NULL, .print = print_vtx_freq + }, + { + .title = "POWER", + .update = update_vtx_power, + .print = print_vtx_power } } }, @@ -628,6 +655,49 @@ void show_menu(void) { max7456_write_string(">", cursor_x + cursor_y * OSD_LINE_LENGTH); } +// Write the artifical horizon to the screen buffer +void osdDrawArtificialHorizon(int rollAngle, int pitchAngle, uint8_t show_sidebars) { + uint16_t position = 194; + MAX7456_CHAR_TYPE *screenBuffer = max7456_get_screen_buffer(); + + if (pitchAngle > AHIPITCHMAX) + pitchAngle = AHIPITCHMAX; + if (pitchAngle < -AHIPITCHMAX) + pitchAngle = -AHIPITCHMAX; + if (rollAngle > AHIROLLMAX) + rollAngle = AHIROLLMAX; + if (rollAngle < -AHIROLLMAX) + rollAngle = -AHIROLLMAX; + + for (uint8_t X = 0; X <= 8; X++) { + if (X == 4) + X = 5; + int Y = (rollAngle * (4 - X)) / 64; + Y -= pitchAngle / 8; + Y += 41; + if (Y >= 0 && Y <= 81) { + uint16_t pos = position - 7 + LINE * (Y / 9) + 3 - 4 * LINE + X; + screenBuffer[pos] = MAX7456_CHAR(SYM_AH_BAR9_0 + (Y % 9)); + } + } + screenBuffer[position - 1] = MAX7456_CHAR(SYM_AH_CENTER_LINE); + screenBuffer[position + 1] = MAX7456_CHAR(SYM_AH_CENTER_LINE_RIGHT); + screenBuffer[position] = MAX7456_CHAR(SYM_AH_CENTER); + + if (show_sidebars) { + // Draw AH sides + int8_t hudwidth = AHISIDEBARWIDTHPOSITION; + int8_t hudheight = AHISIDEBARHEIGHTPOSITION; + for (int8_t X = -hudheight; X <= hudheight; X++) { + screenBuffer[position - hudwidth + (X * LINE)] = MAX7456_CHAR(SYM_AH_DECORATION); + screenBuffer[position + hudwidth + (X * LINE)] = MAX7456_CHAR(SYM_AH_DECORATION); + } + // AH level indicators + screenBuffer[position-hudwidth+1] = MAX7456_CHAR(SYM_AH_LEFT); + screenBuffer[position+hudwidth-1] = MAX7456_CHAR(SYM_AH_RIGHT); + } +} + void updateOsd(void) { static uint8_t skip = 0; @@ -645,86 +715,84 @@ void updateOsd(void) if ( !(skip % 2)) blink = !blink; - if (skip++ & 1) { - if (ARMING_FLAG(ARMED)) { - if (!armed) { - armed = true; - armed_at = now; - in_menu = false; - arming = 5; - } - } else { - if (armed) { - armed = false; - armed_seconds += ((now - armed_at) / 1000000); - } - for (uint8_t channelIndex = 0; channelIndex < 4; channelIndex++) { - sticks[channelIndex] = (constrain(rcData[channelIndex], PWM_RANGE_MIN, PWM_RANGE_MAX) - PWM_RANGE_MIN) * 100 / (PWM_RANGE_MAX - PWM_RANGE_MIN); - } - if (!in_menu && sticks[YAW] > STICKMAX && sticks[THROTTLE] > STICKMIN && sticks[THROTTLE] < STICKMAX && sticks[ROLL] > STICKMIN && sticks[ROLL] < STICKMAX && sticks[PITCH] > STICKMAX) { - in_menu = true; - cursor_row = 255; - cursor_col = 2; - activating_menu = true; - } - } - if (in_menu) { - show_menu(); - } else { - if (batteryWarningVoltage > vbat && blink && masterConfig.osdProfile.item_pos[OSD_VOLTAGE_WARNING] != -1) { - max7456_write_string("LOW VOLTAGE", masterConfig.osdProfile.item_pos[OSD_VOLTAGE_WARNING]); - } - if (arming && blink && masterConfig.osdProfile.item_pos[OSD_ARMED] != -1) { - max7456_write_string("ARMED", masterConfig.osdProfile.item_pos[OSD_ARMED]); - arming--; - } - if (!armed && masterConfig.osdProfile.item_pos[OSD_DISARMED] != -1) { - max7456_write_string("DISARMED", masterConfig.osdProfile.item_pos[OSD_DISARMED]); - } - - if (masterConfig.osdProfile.item_pos[OSD_MAIN_BATT_VOLTAGE] != -1) { - line[0] = SYM_VOLT; - sprintf(line+1, "%d.%1d", vbat / 10, vbat % 10); - max7456_write_string(line, masterConfig.osdProfile.item_pos[OSD_MAIN_BATT_VOLTAGE]); - } - if (masterConfig.osdProfile.item_pos[OSD_RSSI_VALUE] != -1) { - line[0] = SYM_RSSI; - sprintf(line+1, "%d", rssi / 10); - max7456_write_string(line, masterConfig.osdProfile.item_pos[OSD_RSSI_VALUE]); - } - if (masterConfig.osdProfile.item_pos[OSD_THROTTLE_POS] != -1) { - line[0] = SYM_THR; - line[1] = SYM_THR1; - sprintf(line+2, "%3d", (constrain(rcData[THROTTLE], PWM_RANGE_MIN, PWM_RANGE_MAX) - PWM_RANGE_MIN) * 100 / (PWM_RANGE_MAX - PWM_RANGE_MIN)); - max7456_write_string(line, masterConfig.osdProfile.item_pos[OSD_THROTTLE_POS]); - } - if (masterConfig.osdProfile.item_pos[OSD_TIMER] != -1) { - if (armed) { - seconds = armed_seconds + ((now-armed_at) / 1000000); - line[0] = SYM_FLY_M; - sprintf(line+1, " %02d:%02d", seconds / 60, seconds % 60); - } else { - line[0] = SYM_ON_M; - seconds = now / 1000000; - sprintf(line+1, " %02d:%02d", seconds / 60, seconds % 60); - } - max7456_write_string(line, masterConfig.osdProfile.item_pos[OSD_TIMER]); - } - if (masterConfig.osdProfile.item_pos[OSD_CPU_LOAD] != -1) { - print_average_system_load(masterConfig.osdProfile.item_pos[OSD_CPU_LOAD], 0); - } - if (masterConfig.osdProfile.item_pos[OSD_ARTIFICIAL_HORIZON] != -1) { - max7456_artificial_horizon(attitude.values.roll, attitude.values.pitch, masterConfig.osdProfile.item_pos[OSD_HORIZON_SIDEBARS] != -1); - } + if (ARMING_FLAG(ARMED)) { + if (!armed) { + armed = true; + armed_at = now; + in_menu = false; + arming = 5; } } else { - max7456_draw_screen_fast(); + if (armed) { + armed = false; + armed_seconds += ((now - armed_at) / 1000000); + } + for (uint8_t channelIndex = 0; channelIndex < 4; channelIndex++) { + sticks[channelIndex] = (constrain(rcData[channelIndex], PWM_RANGE_MIN, PWM_RANGE_MAX) - PWM_RANGE_MIN) * 100 / (PWM_RANGE_MAX - PWM_RANGE_MIN); + } + if (!in_menu && sticks[YAW] > STICKMAX && sticks[THROTTLE] > STICKMIN && sticks[THROTTLE] < STICKMAX && sticks[ROLL] > STICKMIN && sticks[ROLL] < STICKMAX && sticks[PITCH] > STICKMAX) { + in_menu = true; + cursor_row = 255; + cursor_col = 2; + activating_menu = true; + } } + if (in_menu) { + show_menu(); + } else { + if (batteryWarningVoltage > vbat && blink && masterConfig.osdProfile.item_pos[OSD_VOLTAGE_WARNING] != -1) { + max7456_write_string("LOW VOLTAGE", masterConfig.osdProfile.item_pos[OSD_VOLTAGE_WARNING]); + } + if (arming && blink && masterConfig.osdProfile.item_pos[OSD_ARMED] != -1) { + max7456_write_string("ARMED", masterConfig.osdProfile.item_pos[OSD_ARMED]); + arming--; + } + if (!armed && masterConfig.osdProfile.item_pos[OSD_DISARMED] != -1) { + max7456_write_string("DISARMED", masterConfig.osdProfile.item_pos[OSD_DISARMED]); + } + + if (masterConfig.osdProfile.item_pos[OSD_MAIN_BATT_VOLTAGE] != -1) { + line[0] = SYM_VOLT; + sprintf(line+1, "%d.%1d", vbat / 10, vbat % 10); + max7456_write_string(line, masterConfig.osdProfile.item_pos[OSD_MAIN_BATT_VOLTAGE]); + } + if (masterConfig.osdProfile.item_pos[OSD_RSSI_VALUE] != -1) { + line[0] = SYM_RSSI; + sprintf(line+1, "%d", rssi / 10); + max7456_write_string(line, masterConfig.osdProfile.item_pos[OSD_RSSI_VALUE]); + } + if (masterConfig.osdProfile.item_pos[OSD_THROTTLE_POS] != -1) { + line[0] = SYM_THR; + line[1] = SYM_THR1; + sprintf(line+2, "%3d", (constrain(rcData[THROTTLE], PWM_RANGE_MIN, PWM_RANGE_MAX) - PWM_RANGE_MIN) * 100 / (PWM_RANGE_MAX - PWM_RANGE_MIN)); + max7456_write_string(line, masterConfig.osdProfile.item_pos[OSD_THROTTLE_POS]); + } + if (masterConfig.osdProfile.item_pos[OSD_TIMER] != -1) { + if (armed) { + seconds = armed_seconds + ((now-armed_at) / 1000000); + line[0] = SYM_FLY_M; + sprintf(line+1, " %02d:%02d", seconds / 60, seconds % 60); + } else { + line[0] = SYM_ON_M; + seconds = now / 1000000; + sprintf(line+1, " %02d:%02d", seconds / 60, seconds % 60); + } + max7456_write_string(line, masterConfig.osdProfile.item_pos[OSD_TIMER]); + } + if (masterConfig.osdProfile.item_pos[OSD_CPU_LOAD] != -1) { + print_average_system_load(masterConfig.osdProfile.item_pos[OSD_CPU_LOAD], 0); + } + if (masterConfig.osdProfile.item_pos[OSD_ARTIFICIAL_HORIZON] != -1) { + osdDrawArtificialHorizon(attitude.values.roll, attitude.values.pitch, masterConfig.osdProfile.item_pos[OSD_HORIZON_SIDEBARS] != -1); + } + } + max7456_draw_screen(); } void osdInit(void) { uint16_t x; + MAX7456_CHAR_TYPE* screen_buffer = max7456_get_screen_buffer(); max7456_init(masterConfig.osdProfile.video_system); @@ -732,7 +800,8 @@ void osdInit(void) x = 160; for (int i = 1; i < 5; i++) { for (int j = 3; j < 27; j++) - max7456_screen[i * LINE + j] = (char)x++; + if (x != 255) + screen_buffer[(i * LINE + j)] = MAX7456_CHAR(x++); } sprintf(string_buffer, "BF VERSION: %s", FC_VERSION_STRING); max7456_write_string(string_buffer, LINE06 + 5); diff --git a/src/main/target/SIRINFPV/target.h b/src/main/target/SIRINFPV/target.h index c27b1ec689..fbbaf6b7b9 100644 --- a/src/main/target/SIRINFPV/target.h +++ b/src/main/target/SIRINFPV/target.h @@ -112,6 +112,13 @@ #define MAX7456_SPI_INSTANCE SPI3 #define MAX7456_SPI_CS_PIN PA15 +#define MAX7456_DMA_CHANNEL_TX DMA2_Channel2 +#define MAX7456_DMA_CHANNEL_RX DMA2_Channel1 +#define MAX7456_DMA_TC_FLAG DMA2_FLAG_TC1 +#define MAX7456_DMA_PERIPH_CLOCK RCC_AHBPeriph_DMA2 +#define MAX7456_DMA_IRQ_HANDLER_FUNCTION DMA2_Channel1_IRQHandler +#define MAX7456_DMA_IRQ_HANDLER_ID DMA2_Channel1_IRQn + #define USE_RTC6705 #define RTC6705_SPIDATA_PIN PC15 #define RTC6705_SPILE_PIN PC14 From 6068d5daba29e2e62c87318be97649952b6f122e Mon Sep 17 00:00:00 2001 From: Evgeny Sychov Date: Mon, 27 Jun 2016 15:31:48 -0700 Subject: [PATCH 2/6] Fix blinking --- src/main/io/osd.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 909ee931e0..a508c66bd8 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -700,8 +700,7 @@ void osdDrawArtificialHorizon(int rollAngle, int pitchAngle, uint8_t show_sideba void updateOsd(void) { - static uint8_t skip = 0; - static bool blink = false; + static uint8_t blink = 0; static uint8_t arming = 0; uint32_t seconds; char line[30]; @@ -712,8 +711,7 @@ void updateOsd(void) return; } next_osd_update_at = now + OSD_UPDATE_FREQUENCY; - if ( !(skip % 2)) - blink = !blink; + blink++; if (ARMING_FLAG(ARMED)) { if (!armed) { @@ -740,10 +738,10 @@ void updateOsd(void) if (in_menu) { show_menu(); } else { - if (batteryWarningVoltage > vbat && blink && masterConfig.osdProfile.item_pos[OSD_VOLTAGE_WARNING] != -1) { + if (batteryWarningVoltage > vbat && (blink & 1) && masterConfig.osdProfile.item_pos[OSD_VOLTAGE_WARNING] != -1) { max7456_write_string("LOW VOLTAGE", masterConfig.osdProfile.item_pos[OSD_VOLTAGE_WARNING]); } - if (arming && blink && masterConfig.osdProfile.item_pos[OSD_ARMED] != -1) { + if (arming && (blink & 1) && masterConfig.osdProfile.item_pos[OSD_ARMED] != -1) { max7456_write_string("ARMED", masterConfig.osdProfile.item_pos[OSD_ARMED]); arming--; } From 2d070a35076b5c116d8505d3974dfc84cffbd4b3 Mon Sep 17 00:00:00 2001 From: Evgeny Sychov Date: Fri, 1 Jul 2016 01:53:45 -0700 Subject: [PATCH 3/6] Re-design DMA driver --- src/main/drivers/dma.c | 93 ++++----- src/main/drivers/dma.h | 91 +++++++-- src/main/drivers/dma_stm32f4xx.c | 75 ++++--- src/main/drivers/light_ws2811strip.c | 11 +- .../drivers/light_ws2811strip_stm32f10x.c | 17 +- .../drivers/light_ws2811strip_stm32f30x.c | 17 +- .../drivers/light_ws2811strip_stm32f4xx.c | 31 ++- src/main/drivers/max7456.c | 20 +- src/main/drivers/max7456_symbols.h | 2 +- src/main/drivers/serial_uart_stm32f10x.c | 39 ++-- src/main/drivers/serial_uart_stm32f30x.c | 84 +++----- src/main/drivers/serial_uart_stm32f4xx.c | 185 +++--------------- src/main/drivers/transponder_ir.c | 10 +- src/main/drivers/transponder_ir_stm32f30x.c | 9 +- src/main/target/OMNIBUS/target.h | 4 +- src/main/target/SIRINFPV/target.h | 5 +- 16 files changed, 299 insertions(+), 394 deletions(-) diff --git a/src/main/drivers/dma.c b/src/main/drivers/dma.c index cd17553e08..cbcaa5eafb 100644 --- a/src/main/drivers/dma.c +++ b/src/main/drivers/dma.c @@ -23,61 +23,66 @@ #include "build_config.h" +#include "drivers/nvic.h" #include "drivers/dma.h" /* - * DMA handlers for DMA resources that are shared between different features depending on run-time configuration. + * DMA descriptors. */ -static dmaHandlers_t dmaHandlers; +static dmaChannelDescriptor_t dmaDescriptors[] = { + DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel1, 0, DMA1_Channel1_IRQn, RCC_AHBPeriph_DMA1), + DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel2, 4, DMA1_Channel2_IRQn, RCC_AHBPeriph_DMA1), + DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel3, 8, DMA1_Channel3_IRQn, RCC_AHBPeriph_DMA1), + DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel4, 12, DMA1_Channel4_IRQn, RCC_AHBPeriph_DMA1), + DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel5, 16, DMA1_Channel5_IRQn, RCC_AHBPeriph_DMA1), + DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel6, 20, DMA1_Channel6_IRQn, RCC_AHBPeriph_DMA1), + DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel7, 24, DMA1_Channel7_IRQn, RCC_AHBPeriph_DMA1), +#if defined(STM32F3) || defined(STM32F10X_CL) + DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel1, 0, DMA2_Channel1_IRQn, RCC_AHBPeriph_DMA2), + DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel2, 4, DMA2_Channel2_IRQn, RCC_AHBPeriph_DMA2), + DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel3, 8, DMA2_Channel3_IRQn, RCC_AHBPeriph_DMA2), + DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel4, 12, DMA2_Channel4_IRQn, RCC_AHBPeriph_DMA2), + DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel5, 16, DMA2_Channel5_IRQn, RCC_AHBPeriph_DMA2), +#endif +}; -void dmaNoOpHandler(DMA_Channel_TypeDef *channel) -{ - UNUSED(channel); -} +/* + * DMA IRQ Handlers + */ +DEFINE_DMA_IRQ_HANDLER(1, 1, DMA1_CH1_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 2, DMA1_CH2_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 3, DMA1_CH3_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 4, DMA1_CH4_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 5, DMA1_CH5_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 6, DMA1_CH6_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 7, DMA1_CH7_HANDLER) -void DMA1_Channel2_IRQHandler(void) -{ - dmaHandlers.dma1Channel2IRQHandler(DMA1_Channel2); -} +#if defined(STM32F3) || defined(STM32F10X_CL) +DEFINE_DMA_IRQ_HANDLER(2, 1, DMA2_CH1_HANDLER) +DEFINE_DMA_IRQ_HANDLER(2, 2, DMA2_CH2_HANDLER) +DEFINE_DMA_IRQ_HANDLER(2, 3, DMA2_CH3_HANDLER) +DEFINE_DMA_IRQ_HANDLER(2, 4, DMA2_CH4_HANDLER) +DEFINE_DMA_IRQ_HANDLER(2, 5, DMA2_CH5_HANDLER) +#endif -void DMA1_Channel3_IRQHandler(void) -{ - dmaHandlers.dma1Channel3IRQHandler(DMA1_Channel3); -} - -void DMA1_Channel6_IRQHandler(void) -{ - dmaHandlers.dma1Channel6IRQHandler(DMA1_Channel6); -} - -void DMA1_Channel7_IRQHandler(void) -{ - dmaHandlers.dma1Channel7IRQHandler(DMA1_Channel7); -} void dmaInit(void) { - memset(&dmaHandlers, 0, sizeof(dmaHandlers)); - dmaHandlers.dma1Channel2IRQHandler = dmaNoOpHandler; - dmaHandlers.dma1Channel3IRQHandler = dmaNoOpHandler; - dmaHandlers.dma1Channel6IRQHandler = dmaNoOpHandler; - dmaHandlers.dma1Channel7IRQHandler = dmaNoOpHandler; + // TODO: Do we need this? } -void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback) +void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam) { - switch (identifier) { - case DMA1_CH2_HANDLER: - dmaHandlers.dma1Channel2IRQHandler = callback; - break; - case DMA1_CH3_HANDLER: - dmaHandlers.dma1Channel3IRQHandler = callback; - break; - case DMA1_CH6_HANDLER: - dmaHandlers.dma1Channel6IRQHandler = callback; - break; - case DMA1_CH7_HANDLER: - dmaHandlers.dma1Channel7IRQHandler = callback; - break; - } + NVIC_InitTypeDef NVIC_InitStructure; + + RCC_AHBPeriphClockCmd(dmaDescriptors[identifier].rrc, ENABLE); + dmaDescriptors[identifier].irqHandlerCallback = callback; + dmaDescriptors[identifier].userParam = userParam; + + NVIC_InitStructure.NVIC_IRQChannel = dmaDescriptors[identifier].irqN; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(priority); + NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(priority); + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); } + diff --git a/src/main/drivers/dma.h b/src/main/drivers/dma.h index 9cb34c7665..345c7b2ed8 100644 --- a/src/main/drivers/dma.h +++ b/src/main/drivers/dma.h @@ -15,37 +15,98 @@ * along with Cleanflight. If not, see . */ + +struct dmaChannelDescriptor_s; +typedef void (*dmaCallbackHandlerFuncPtr)(struct dmaChannelDescriptor_s *channelDescriptor); + #ifdef STM32F4 typedef void(*dmaCallbackHandlerFuncPtr)(DMA_Stream_TypeDef *stream); typedef enum { - DMA1_ST2_HANDLER = 0, + DMA1_ST1_HANDLER = 0, + DMA1_ST2_HANDLER, + DMA1_ST3_HANDLER, + DMA1_ST4_HANDLER, + DMA1_ST5_HANDLER, + DMA1_ST6_HANDLER, DMA1_ST7_HANDLER, + DMA2_ST1_HANDLER, + DMA2_ST2_HANDLER, + DMA2_ST3_HANDLER, + DMA2_ST4_HANDLER, + DMA2_ST5_HANDLER, + DMA2_ST6_HANDLER, + DMA2_ST7_HANDLER, } dmaHandlerIdentifier_e; -typedef struct dmaHandlers_s { - dmaCallbackHandlerFuncPtr dma1Stream2IRQHandler; - dmaCallbackHandlerFuncPtr dma1Stream7IRQHandler; -} dmaHandlers_t; +typedef struct dmaChannelDescriptor_s { + DMA_TypeDef* dma; + DMA_Stream_TypeDef* stream; + dmaCallbackHandlerFuncPtr irqHandlerCallback; + uint8_t flagsShift; + IRQn_Type irqN; + uint32_t rrc; + uint32_t userParam; +} dmaChannelDescriptor_t; + +#define DEFINE_DMA_CHANNEL(d, s, f, i, r) {.dma = d, .stream = s, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rrc = r, .userParam = 0} +#define DEFINE_DMA_IRQ_HANDLER(d, s, i) void DMA ## d ## _Stream ## s ## _IRQHandler(void) {\ + if (dmaDescriptors[i].irqHandlerCallback)\ + dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\ + } + +#define DMA_CLEAR_FLAG(d, flag) d->flagsShift > 31 ? d->dma->HIFCR = (flag << (d->flagsShift - 32)) : d->dma->LIFCR = (flag << d->flagsShift) +#define DMA_GET_FLAG_STATUS(d, flag) (d->flagsShift > 31 ? d->dma->HISR & (flag << (d->flagsShift - 32)): d->dma->LISR & (flag << d->flagsShift)) + + +#define DMA_IT_TCIF ((uint32_t)0x00000020) +#define DMA_IT_HTIF ((uint32_t)0x00000010) +#define DMA_IT_TEIF ((uint32_t)0x00000008) +#define DMA_IT_DMEIF ((uint32_t)0x00000004) +#define DMA_IT_FEIF ((uint32_t)0x00000001) #else -typedef void (*dmaCallbackHandlerFuncPtr)(DMA_Channel_TypeDef *channel); - typedef enum { - DMA1_CH2_HANDLER = 0, + DMA1_CH1_HANDLER = 0, + DMA1_CH2_HANDLER, DMA1_CH3_HANDLER, + DMA1_CH4_HANDLER, + DMA1_CH5_HANDLER, DMA1_CH6_HANDLER, DMA1_CH7_HANDLER, + DMA2_CH1_HANDLER, + DMA2_CH2_HANDLER, + DMA2_CH3_HANDLER, + DMA2_CH4_HANDLER, + DMA2_CH5_HANDLER, } dmaHandlerIdentifier_e; -typedef struct dmaHandlers_s { - dmaCallbackHandlerFuncPtr dma1Channel2IRQHandler; - dmaCallbackHandlerFuncPtr dma1Channel3IRQHandler; - dmaCallbackHandlerFuncPtr dma1Channel6IRQHandler; - dmaCallbackHandlerFuncPtr dma1Channel7IRQHandler; -} dmaHandlers_t; +typedef struct dmaChannelDescriptor_s { + DMA_TypeDef* dma; + DMA_Channel_TypeDef* channel; + dmaCallbackHandlerFuncPtr irqHandlerCallback; + uint8_t flagsShift; + IRQn_Type irqN; + uint32_t rrc; + uint32_t userParam; +} dmaChannelDescriptor_t; + +#define DEFINE_DMA_CHANNEL(d, c, f, i, r) {.dma = d, .channel = c, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rrc = r, .userParam = 0} +#define DEFINE_DMA_IRQ_HANDLER(d, c, i) void DMA ## d ## _Channel ## c ## _IRQHandler(void) {\ + if (dmaDescriptors[i].irqHandlerCallback)\ + dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\ + } + +#define DMA_CLEAR_FLAG(d, flag) d->dma->IFCR = (flag << d->flagsShift) +#define DMA_GET_FLAG_STATUS(d, flag) (d->dma->ISR & (flag << d->flagsShift)) + +#define DMA_IT_TCIF ((uint32_t)0x00000002) +#define DMA_IT_HTIF ((uint32_t)0x00000004) +#define DMA_IT_TEIF ((uint32_t)0x00000008) + #endif void dmaInit(void); -void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback); +void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam); + diff --git a/src/main/drivers/dma_stm32f4xx.c b/src/main/drivers/dma_stm32f4xx.c index fefbae2801..3f57dfd985 100644 --- a/src/main/drivers/dma_stm32f4xx.c +++ b/src/main/drivers/dma_stm32f4xx.c @@ -23,43 +23,66 @@ #include "build_config.h" +#include "drivers/nvic.h" #include "drivers/dma.h" /* - * DMA handlers for DMA resources that are shared between different features depending on run-time configuration. + * DMA descriptors. */ -static dmaHandlers_t dmaHandlers; +static dmaChannelDescriptor_t dmaDescriptors[] = { + DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream0, 0, DMA1_Stream0_IRQn, RCC_AHB1Periph_DMA1), + DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream1, 6, DMA1_Stream1_IRQn, RCC_AHB1Periph_DMA1), + DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream2, 16, DMA1_Stream2_IRQn, RCC_AHB1Periph_DMA1), + DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream3, 22, DMA1_Stream3_IRQn, RCC_AHB1Periph_DMA1), + DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream4, 32, DMA1_Stream4_IRQn, RCC_AHB1Periph_DMA1), + DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream5, 38, DMA1_Stream5_IRQn, RCC_AHB1Periph_DMA1), + DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream6, 48, DMA1_Stream6_IRQn, RCC_AHB1Periph_DMA1), + DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream7, 54, DMA1_Stream7_IRQn, RCC_AHB1Periph_DMA1), -void dmaNoOpHandler(DMA_Stream_TypeDef *stream) -{ - UNUSED(stream); -} + DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream0, 0, DMA2_Stream0_IRQn, RCC_AHB1Periph_DMA2), + DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream1, 6, DMA2_Stream1_IRQn, RCC_AHB1Periph_DMA2), + DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream2, 16, DMA2_Stream2_IRQn, RCC_AHB1Periph_DMA2), + DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream3, 22, DMA2_Stream3_IRQn, RCC_AHB1Periph_DMA2), + DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream4, 32, DMA2_Stream4_IRQn, RCC_AHB1Periph_DMA2), + DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream5, 38, DMA2_Stream5_IRQn, RCC_AHB1Periph_DMA2), + DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream6, 48, DMA2_Stream6_IRQn, RCC_AHB1Periph_DMA2), + DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream7, 54, DMA2_Stream7_IRQn, RCC_AHB1Periph_DMA2), -void DMA1_Stream2_IRQHandler(void) -{ - dmaHandlers.dma1Stream2IRQHandler(DMA1_Stream2); -} +}; + +/* + * DMA IRQ Handlers + */ +DEFINE_DMA_IRQ_HANDLER(1, 1, DMA1_CH1_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 2, DMA1_CH2_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 3, DMA1_CH3_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 4, DMA1_CH4_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 5, DMA1_CH5_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 6, DMA1_CH6_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 7, DMA1_CH7_HANDLER) +DEFINE_DMA_IRQ_HANDLER(2, 1, DMA2_CH1_HANDLER) +DEFINE_DMA_IRQ_HANDLER(2, 2, DMA2_CH2_HANDLER) +DEFINE_DMA_IRQ_HANDLER(2, 3, DMA2_CH3_HANDLER) +DEFINE_DMA_IRQ_HANDLER(2, 4, DMA2_CH4_HANDLER) +DEFINE_DMA_IRQ_HANDLER(2, 5, DMA2_CH5_HANDLER) -void DMA1_Stream7_IRQHandler(void) -{ - dmaHandlers.dma1Stream7IRQHandler(DMA1_Stream7); -} void dmaInit(void) { - memset(&dmaHandlers, 0, sizeof(dmaHandlers)); - dmaHandlers.dma1Stream2IRQHandler = dmaNoOpHandler; - dmaHandlers.dma1Stream7IRQHandler = dmaNoOpHandler; + // TODO: Do we need this? } -void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback) +void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority) { - switch (identifier) { - case DMA1_ST2_HANDLER: - dmaHandlers.dma1Stream2IRQHandler = callback; - break; - case DMA1_ST7_HANDLER: - dmaHandlers.dma1Stream7IRQHandler = callback; - break; - } + NVIC_InitTypeDef NVIC_InitStructure; + + RCC_AHB1PeriphClockCmd(dmaDescriptors[identifier].periphClk, ENABLE); + dmaDescriptors[identifier].irqHandlerCallback = callback; + + NVIC_InitStructure.NVIC_IRQChannel = dmaDescriptors[identifier].irqN; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(priority); + NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(priority); + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); } + diff --git a/src/main/drivers/light_ws2811strip.c b/src/main/drivers/light_ws2811strip.c index 3821350f57..75dac72d43 100644 --- a/src/main/drivers/light_ws2811strip.c +++ b/src/main/drivers/light_ws2811strip.c @@ -80,18 +80,9 @@ void setStripColors(const hsvColor_t *colors) } } -void ws2811DMAHandler(DMA_Channel_TypeDef *channel) { - if (DMA_GetFlagStatus(WS2811_DMA_TC_FLAG)) { - ws2811LedDataTransferInProgress = 0; - DMA_Cmd(channel, DISABLE); - DMA_ClearFlag(WS2811_DMA_TC_FLAG); - } -} - void ws2811LedStripInit(void) { memset(&ledStripDMABuffer, 0, WS2811_DMA_BUFFER_SIZE); - dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, ws2811DMAHandler); ws2811LedStripHardwareInit(); ws2811UpdateStrip(); } @@ -173,4 +164,4 @@ void ws2811UpdateStrip(void) ws2811LedStripDMAEnable(); } -#endif \ No newline at end of file +#endif diff --git a/src/main/drivers/light_ws2811strip_stm32f10x.c b/src/main/drivers/light_ws2811strip_stm32f10x.c index b7f1bd4138..f780901f1c 100644 --- a/src/main/drivers/light_ws2811strip_stm32f10x.c +++ b/src/main/drivers/light_ws2811strip_stm32f10x.c @@ -23,6 +23,15 @@ #include "common/color.h" #include "drivers/light_ws2811strip.h" #include "nvic.h" +#include "dma.h" + +static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor) { + if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) { + ws2811LedDataTransferInProgress = 0; + DMA_Cmd(descriptor->channel, DISABLE); + DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); + } +} void ws2811LedStripHardwareInit(void) { @@ -100,13 +109,7 @@ void ws2811LedStripHardwareInit(void) DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE); - NVIC_InitTypeDef NVIC_InitStructure; - - NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_WS2811_DMA); - NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_WS2811_DMA); - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); + dmaSetHandler(DMA1_CH6_HANDLER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0); setStripColor(&hsv_white); ws2811UpdateStrip(); diff --git a/src/main/drivers/light_ws2811strip_stm32f30x.c b/src/main/drivers/light_ws2811strip_stm32f30x.c index fbcc8d3fb0..9deaff9e4b 100644 --- a/src/main/drivers/light_ws2811strip_stm32f30x.c +++ b/src/main/drivers/light_ws2811strip_stm32f30x.c @@ -22,6 +22,7 @@ #include "gpio.h" #include "nvic.h" +#include "dma.h" #include "common/color.h" #include "drivers/light_ws2811strip.h" @@ -41,6 +42,14 @@ #endif +static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor) { + if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) { + ws2811LedDataTransferInProgress = 0; + DMA_Cmd(descriptor->channel, DISABLE); + DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); + } +} + void ws2811LedStripHardwareInit(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; @@ -114,13 +123,7 @@ void ws2811LedStripHardwareInit(void) DMA_ITConfig(WS2811_DMA_CHANNEL, DMA_IT_TC, ENABLE); - NVIC_InitTypeDef NVIC_InitStructure; - - NVIC_InitStructure.NVIC_IRQChannel = WS2811_IRQ; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_WS2811_DMA); - NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_WS2811_DMA); - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); + dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0); setStripColor(&hsv_white); ws2811UpdateStrip(); diff --git a/src/main/drivers/light_ws2811strip_stm32f4xx.c b/src/main/drivers/light_ws2811strip_stm32f4xx.c index d85f1c5757..65e1d51819 100644 --- a/src/main/drivers/light_ws2811strip_stm32f4xx.c +++ b/src/main/drivers/light_ws2811strip_stm32f4xx.c @@ -23,8 +23,20 @@ #include "common/color.h" #include "light_ws2811strip.h" #include "nvic.h" +#include "dma.h" #ifdef LED_STRIP + +static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor) +{ + if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) { + ws2811LedDataTransferInProgress = 0; + DMA_Cmd(descriptor->stream, DISABLE); + TIM_DMACmd(TIM5, TIM_DMA_CC1, DISABLE); + DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); + } +} + void ws2811LedStripHardwareInit(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; @@ -98,28 +110,11 @@ void ws2811LedStripHardwareInit(void) DMA_ITConfig(DMA1_Stream2, DMA_IT_TC, ENABLE); DMA_ClearITPendingBit(DMA1_Stream2, DMA_IT_TCIF2); // clear DMA1 Channel 6 transfer complete flag - NVIC_InitTypeDef NVIC_InitStructure; - - NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream2_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_WS2811_DMA); - NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_WS2811_DMA); - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - + dmaSetHandler(DMA1_ST2_HANDLER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0); setStripColor(&hsv_white); ws2811UpdateStrip(); } -void DMA1_Stream2_IRQHandler(void) -{ - if (DMA_GetFlagStatus(DMA1_Stream2, DMA_FLAG_TCIF2)) { - ws2811LedDataTransferInProgress = 0; - DMA_Cmd(DMA1_Stream2, DISABLE); - TIM_DMACmd(TIM5, TIM_DMA_CC1, DISABLE); - DMA_ClearITPendingBit(DMA1_Stream2, DMA_IT_TCIF2); - } -} - void ws2811LedStripDMAEnable(void) { DMA_SetCurrDataCounter(DMA1_Stream2, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred diff --git a/src/main/drivers/max7456.c b/src/main/drivers/max7456.c index 239c294125..eeefa940d9 100644 --- a/src/main/drivers/max7456.c +++ b/src/main/drivers/max7456.c @@ -30,6 +30,7 @@ #include "drivers/light_led.h" #include "drivers/system.h" #include "drivers/nvic.h" +#include "drivers/dma.h" #include "max7456.h" #include "max7456_symbols.h" @@ -119,8 +120,8 @@ static void max7456_send_dma(void* tx_buffer, void* rx_buffer, uint16_t buffer_s SPI_I2S_DMAReq_Tx, ENABLE); } -void MAX7456_DMA_IRQ_HANDLER_FUNCTION (void) { - if (DMA_GetFlagStatus(MAX7456_DMA_TC_FLAG)) { +void max7456_dma_irq_handler(dmaChannelDescriptor_t* descriptor) { + if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) { #ifdef MAX7456_DMA_CHANNEL_RX DMA_Cmd(MAX7456_DMA_CHANNEL_RX, DISABLE); #else @@ -131,7 +132,7 @@ void MAX7456_DMA_IRQ_HANDLER_FUNCTION (void) { #endif DMA_Cmd(MAX7456_DMA_CHANNEL_TX, DISABLE); - DMA_ClearFlag(MAX7456_DMA_TC_FLAG); + DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); SPI_I2S_DMACmd(MAX7456_SPI_INSTANCE, #ifdef MAX7456_DMA_CHANNEL_RX @@ -141,7 +142,7 @@ void MAX7456_DMA_IRQ_HANDLER_FUNCTION (void) { DISABLE_MAX7456; for (uint16_t x = 0; x < max_screen_size; x++) - max7456_screen[x + 3] = MAX7456ADD_DMDI; + max7456_screen[x + 3] = MAX7456_CHAR(' '); dma_transaction_in_progress = 0; } } @@ -206,7 +207,7 @@ void max7456_init(uint8_t video_system) delay(100); for (x = 0; x < max_screen_size; x++) - SCREEN_BUFFER[x] = MAX7456_CHAR(0); + SCREEN_BUFFER[x] = MAX7456_CHAR(' '); #ifdef MAX7456_DMA_CHANNEL_TX max7456_screen[0] = (uint16_t)(MAX7456ADD_DMAH | (0 << 8)); @@ -215,14 +216,7 @@ void max7456_init(uint8_t video_system) max7456_screen[max_screen_size + 3] = (uint16_t)(MAX7456ADD_DMDI | (0xFF << 8)); max7456_screen[max_screen_size + 4] = (uint16_t)(MAX7456ADD_DMM | (0 << 8)); - RCC_AHBPeriphClockCmd(MAX7456_DMA_PERIPH_CLOCK, ENABLE); - NVIC_InitTypeDef NVIC_InitStructure; - - NVIC_InitStructure.NVIC_IRQChannel = MAX7456_DMA_IRQ_HANDLER_ID; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_MAX7456_DMA); - NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_MAX7456_DMA); - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); + dmaSetHandler(MAX7456_DMA_IRQ_HANDLER_ID, max7456_dma_irq_handler, NVIC_PRIO_MAX7456_DMA, 0); #endif } diff --git a/src/main/drivers/max7456_symbols.h b/src/main/drivers/max7456_symbols.h index 2030cb956b..b2e8da72b5 100644 --- a/src/main/drivers/max7456_symbols.h +++ b/src/main/drivers/max7456_symbols.h @@ -176,7 +176,7 @@ #define SYM_FT 0x0F // Voltage and amperage -#define SYM_VOLT 0x00 +#define SYM_VOLT 0x06 #define SYM_AMP 0x9A #define SYM_MAH 0xA4 #define SYM_WATT 0x57 diff --git a/src/main/drivers/serial_uart_stm32f10x.c b/src/main/drivers/serial_uart_stm32f10x.c index 08c16fa2f3..999df9bd5b 100644 --- a/src/main/drivers/serial_uart_stm32f10x.c +++ b/src/main/drivers/serial_uart_stm32f10x.c @@ -31,6 +31,7 @@ #include "system.h" #include "gpio.h" #include "nvic.h" +#include "dma.h" #include "serial.h" #include "serial_uart.h" @@ -83,6 +84,22 @@ void usartIrqCallback(uartPort_t *s) } #ifdef USE_USART1 + +// USART1 Tx DMA Handler +void USART1_DMA_IRQHandler(dmaChannelDescriptor_t* descriptor) +{ + uartPort_t *s = &uartPort1; + DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); + DMA_Cmd(descriptor->channel, DISABLE); + + if (s->port.txBufferHead != s->port.txBufferTail) + uartStartTxDMA(s); + else + s->txDMAEmpty = true; +} + + + // USART1 - Telemetry (RX/TX by DMA) uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t options) { @@ -90,7 +107,6 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio static volatile uint8_t rx1Buffer[UART1_RX_BUFFER_SIZE]; static volatile uint8_t tx1Buffer[UART1_TX_BUFFER_SIZE]; gpio_config_t gpio; - NVIC_InitTypeDef NVIC_InitStructure; s = &uartPort1; s->port.vTable = uartVTable; @@ -137,14 +153,12 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio } // DMA TX Interrupt - NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1_TXDMA); - NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1_TXDMA); - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); + dmaSetHandler(DMA1_CH4_HANDLER, USART1_DMA_IRQHandler, NVIC_PRIO_SERIALUART1_TXDMA, 0); #ifndef USE_USART1_RX_DMA // RX/TX Interrupt + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1); @@ -156,19 +170,6 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio } -// USART1 Tx DMA Handler -void DMA1_Channel4_IRQHandler(void) -{ - uartPort_t *s = &uartPort1; - DMA_ClearITPendingBit(DMA1_IT_TC4); - DMA_Cmd(s->txDMAChannel, DISABLE); - - if (s->port.txBufferHead != s->port.txBufferTail) - uartStartTxDMA(s); - else - s->txDMAEmpty = true; -} - // USART1 Rx/Tx IRQ Handler void USART1_IRQHandler(void) { diff --git a/src/main/drivers/serial_uart_stm32f30x.c b/src/main/drivers/serial_uart_stm32f30x.c index c124f05e20..78cfd482a9 100644 --- a/src/main/drivers/serial_uart_stm32f30x.c +++ b/src/main/drivers/serial_uart_stm32f30x.c @@ -32,6 +32,7 @@ #include "system.h" #include "gpio.h" #include "nvic.h" +#include "dma.h" #include "serial.h" #include "serial_uart.h" @@ -81,13 +82,24 @@ static uartPort_t uartPort2; static uartPort_t uartPort3; #endif +static void handleUsartTxDma(dmaChannelDescriptor_t* descriptor) +{ + uartPort_t *s = (uartPort_t*)(descriptor->userParam); + DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); + DMA_Cmd(descriptor->channel, DISABLE); + + if (s->port.txBufferHead != s->port.txBufferTail) + uartStartTxDMA(s); + else + s->txDMAEmpty = true; +} + #ifdef USE_USART1 uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t options) { uartPort_t *s; static volatile uint8_t rx1Buffer[UART1_RX_BUFFER_SIZE]; static volatile uint8_t tx1Buffer[UART1_TX_BUFFER_SIZE]; - NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; s = &uartPort1; @@ -139,14 +151,12 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio } } - // DMA TX Interrupt - NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1_TXDMA); - NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1_TXDMA); - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); + dmaSetHandler(DMA1_CH4_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART1_TXDMA, 0); + #ifndef USE_USART1_RX_DMA + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART1_RXDMA); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART1_RXDMA); @@ -164,7 +174,6 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t optio uartPort_t *s; static volatile uint8_t rx2Buffer[UART2_RX_BUFFER_SIZE]; static volatile uint8_t tx2Buffer[UART2_TX_BUFFER_SIZE]; - NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; s = &uartPort2; @@ -222,14 +231,12 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t optio #ifdef USE_USART2_TX_DMA // DMA TX Interrupt - NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART2_TXDMA); - NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART2_TXDMA); - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); + dmaSetHandler(DMA1_CH7_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART2_TXDMA, 0); #endif #ifndef USE_USART2_RX_DMA + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART2_RXDMA); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART2_RXDMA); @@ -247,7 +254,6 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio uartPort_t *s; static volatile uint8_t rx3Buffer[UART3_RX_BUFFER_SIZE]; static volatile uint8_t tx3Buffer[UART3_TX_BUFFER_SIZE]; - NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; s = &uartPort3; @@ -305,14 +311,12 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio #ifdef USE_USART3_TX_DMA // DMA TX Interrupt - NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART3_TXDMA); - NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART3_TXDMA); - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); + dmaSetHandler(DMA1_CH2_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART3_TXDMA, 0); #endif #ifndef USE_USART3_RX_DMA + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_SERIALUART3_RXDMA); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_SERIALUART3_RXDMA); @@ -324,48 +328,6 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio } #endif -static void handleUsartTxDma(uartPort_t *s) -{ - DMA_Cmd(s->txDMAChannel, DISABLE); - - if (s->port.txBufferHead != s->port.txBufferTail) - uartStartTxDMA(s); - else - s->txDMAEmpty = true; -} - -// USART1 Tx DMA Handler -void DMA1_Channel4_IRQHandler(void) -{ - uartPort_t *s = &uartPort1; - DMA_ClearITPendingBit(DMA1_IT_TC4); - DMA_Cmd(DMA1_Channel4, DISABLE); - handleUsartTxDma(s); -} - -#ifdef USE_USART2_TX_DMA -// USART2 Tx DMA Handler -void DMA1_Channel7_IRQHandler(void) -{ - uartPort_t *s = &uartPort2; - DMA_ClearITPendingBit(DMA1_IT_TC7); - DMA_Cmd(DMA1_Channel7, DISABLE); - handleUsartTxDma(s); -} -#endif - -// USART3 Tx DMA Handler -#ifdef USE_USART3_TX_DMA -void DMA1_Channel2_IRQHandler(void) -{ - uartPort_t *s = &uartPort3; - DMA_ClearITPendingBit(DMA1_IT_TC2); - DMA_Cmd(DMA1_Channel2, DISABLE); - handleUsartTxDma(s); -} -#endif - - void usartIrqHandler(uartPort_t *s) { uint32_t ISR = s->USARTx->ISR; diff --git a/src/main/drivers/serial_uart_stm32f4xx.c b/src/main/drivers/serial_uart_stm32f4xx.c index f5bba84699..d8c8ee5df5 100644 --- a/src/main/drivers/serial_uart_stm32f4xx.c +++ b/src/main/drivers/serial_uart_stm32f4xx.c @@ -87,7 +87,7 @@ static uartDevice_t uart1 = .rcc_ahb1 = USART1_AHB1_PERIPHERALS, #endif .rcc_apb2 = RCC_APB2(USART1), - .txIrq = DMA2_Stream7_IRQn, + .txIrq = DMA2_ST7_HANDLER, .rxIrq = USART1_IRQn, .txPriority = NVIC_PRIO_SERIALUART1_TXDMA, .rxPriority = NVIC_PRIO_SERIALUART1 @@ -110,7 +110,7 @@ static uartDevice_t uart2 = .rcc_ahb1 = USART2_AHB1_PERIPHERALS, #endif .rcc_apb1 = RCC_APB1(USART2), - .txIrq = DMA1_Stream6_IRQn, + .txIrq = DMA1_ST6_HANDLER, .rxIrq = USART2_IRQn, .txPriority = NVIC_PRIO_SERIALUART2_TXDMA, .rxPriority = NVIC_PRIO_SERIALUART2 @@ -133,7 +133,7 @@ static uartDevice_t uart3 = .rcc_ahb1 = USART3_AHB1_PERIPHERALS, #endif .rcc_apb1 = RCC_APB1(USART3), - .txIrq = DMA1_Stream3_IRQn, + .txIrq = DMA1_ST3_HANDLER, .rxIrq = USART3_IRQn, .txPriority = NVIC_PRIO_SERIALUART3_TXDMA, .rxPriority = NVIC_PRIO_SERIALUART3 @@ -156,7 +156,7 @@ static uartDevice_t uart4 = .rcc_ahb1 = USART4_AHB1_PERIPHERALS, #endif .rcc_apb1 = RCC_APB1(UART4), - .txIrq = DMA1_Stream4_IRQn, + .txIrq = DMA1_ST4_HANDLER, .rxIrq = UART4_IRQn, .txPriority = NVIC_PRIO_SERIALUART4_TXDMA, .rxPriority = NVIC_PRIO_SERIALUART4 @@ -179,7 +179,7 @@ static uartDevice_t uart5 = .rcc_ahb1 = USART5_AHB1_PERIPHERALS, #endif .rcc_apb1 = RCC_APB1(UART5), - .txIrq = DMA2_Stream7_IRQn, + .txIrq = DMA2_ST7_HANDLER, .rxIrq = UART5_IRQn, .txPriority = NVIC_PRIO_SERIALUART5_TXDMA, .rxPriority = NVIC_PRIO_SERIALUART5 @@ -202,7 +202,7 @@ static uartDevice_t uart6 = .rcc_ahb1 = USART6_AHB1_PERIPHERALS, #endif .rcc_apb2 = RCC_APB2(USART6), - .txIrq = DMA2_Stream6_IRQn, + .txIrq = DMA2_ST6_HANDLER, .rxIrq = USART6_IRQn, .txPriority = NVIC_PRIO_SERIALUART6_TXDMA, .rxPriority = NVIC_PRIO_SERIALUART6 @@ -278,6 +278,29 @@ static void handleUsartTxDma(uartPort_t *s) s->txDMAEmpty = true; } +void dmaIRQHandler(dmaChannelDescriptor_t descriptor) +{ + uartPort_t *s = &((uartDevice_t*)(descriptor->userParam)->port); + if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) + { + DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); + DMA_CLEAR_FLAG(descriptor, DMA_IT_HTIF); + if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_FEIF)) + { + DMA_CLEAR_FLAG(descriptor, DMA_IT_FEIF); + } + handleUsartTxDma(s); + } + if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TEIF)) + { + DMA_CLEAR_FLAG(descriptor, DMA_IT_TEIF); + } + if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_DMEIF)) + { + DMA_CLEAR_FLAG(descriptor, DMA_IT_DMEIF); + } +} + uartPort_t *serialUSART(UARTDevice device, uint32_t baudRate, portMode_t mode, portOptions_t options) { uartPort_t *s; @@ -336,11 +359,7 @@ uartPort_t *serialUSART(UARTDevice device, uint32_t baudRate, portMode_t mode, p } // DMA TX Interrupt - NVIC_InitStructure.NVIC_IRQChannel = uart->txIrq; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(uart->txPriority); - NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(uart->txPriority); - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); + dmaSetHandler(uart->txIrq, dmaIRQHandler, uart->txPriority, (uint32_t)uart); if (!(s->rxDMAChannel)) { NVIC_InitStructure.NVIC_IRQChannel = uart->rxIrq; @@ -359,30 +378,6 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio return serialUSART(UARTDEV_1, baudRate, mode, options); } -// USART1 Tx DMA Handler -void DMA2_Stream7_IRQHandler(void) -{ - uartPort_t *s = &(uartHardwareMap[UARTDEV_1]->port); - if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF7)) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF7); - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF7); - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF7)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF7); - } - handleUsartTxDma(s); - } - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF7)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF7); - } - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF7)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF7); - } -} - // USART1 Rx/Tx IRQ Handler void USART1_IRQHandler(void) { @@ -398,30 +393,6 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t optio return serialUSART(UARTDEV_2, baudRate, mode, options); } -// USART2 Tx DMA Handler -void DMA1_Stream6_IRQHandler(void) -{ - uartPort_t *s = &(uartHardwareMap[UARTDEV_2]->port); - if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF6)) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF6); - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF6); - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF6)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF6); - } - handleUsartTxDma(s); - } - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF6)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF6); - } - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF6)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF6); - } -} - void USART2_IRQHandler(void) { uartPort_t *s = &(uartHardwareMap[UARTDEV_2]->port); @@ -436,30 +407,6 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio return serialUSART(UARTDEV_3, baudRate, mode, options); } -// USART3 Tx DMA Handler -void DMA1_Stream3_IRQHandler(void) -{ - uartPort_t *s = &(uartHardwareMap[UARTDEV_3]->port); - if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF3)) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF3); - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF3); - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF3)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF3); - } - handleUsartTxDma(s); - } - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF3)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF3); - } - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF3)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF3); - } -} - void USART3_IRQHandler(void) { uartPort_t *s = &(uartHardwareMap[UARTDEV_3]->port); @@ -474,30 +421,6 @@ uartPort_t *serialUSART4(uint32_t baudRate, portMode_t mode, portOptions_t optio return serialUSART(UARTDEV_4, baudRate, mode, options); } -// USART4 Tx DMA Handler -void DMA1_Stream4_IRQHandler(void) -{ - uartPort_t *s = &(uartHardwareMap[UARTDEV_4]->port); - if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF4)) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF4); - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF4); - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF4)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF4); - } - handleUsartTxDma(s); - } - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF4)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF4); - } - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF4)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF4); - } -} - void UART4_IRQHandler(void) { uartPort_t *s = &(uartHardwareMap[UARTDEV_4]->port); @@ -512,30 +435,6 @@ uartPort_t *serialUSART5(uint32_t baudRate, portMode_t mode, portOptions_t optio return serialUSART(UARTDEV_5, baudRate, mode, options); } -// USART5 Tx DMA Handler -void DMA1_Stream7_IRQHandler(void) -{ - uartPort_t *s = &(uartHardwareMap[UARTDEV_5]->port); - if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF7)) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF7); - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF7); - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF7)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF7); - } - handleUsartTxDma(s); - } - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF7)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF7); - } - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF7)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF7); - } -} - void UART5_IRQHandler(void) { uartPort_t *s = &(uartHardwareMap[UARTDEV_5]->port); @@ -550,30 +449,6 @@ uartPort_t *serialUSART6(uint32_t baudRate, portMode_t mode, portOptions_t optio return serialUSART(UARTDEV_6, baudRate, mode, options); } -// USART6 Tx DMA Handler -void DMA2_Stream6_IRQHandler(void) -{ - uartPort_t *s = &(uartHardwareMap[UARTDEV_6]->port); - if(DMA_GetITStatus(s->txDMAStream,DMA_IT_TCIF6)) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TCIF6); - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_HTIF6); - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_FEIF6)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_FEIF6); - } - handleUsartTxDma(s); - } - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_TEIF6)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_TEIF6); - } - if(DMA_GetFlagStatus(s->txDMAStream,DMA_IT_DMEIF6)==SET) - { - DMA_ClearITPendingBit(s->txDMAStream,DMA_IT_DMEIF6); - } -} - void USART6_IRQHandler(void) { uartPort_t *s = &(uartHardwareMap[UARTDEV_6]->port); diff --git a/src/main/drivers/transponder_ir.c b/src/main/drivers/transponder_ir.c index 51d47e44e5..8e95ac33bf 100644 --- a/src/main/drivers/transponder_ir.c +++ b/src/main/drivers/transponder_ir.c @@ -38,19 +38,19 @@ uint8_t transponderIrDMABuffer[TRANSPONDER_DMA_BUFFER_SIZE]; volatile uint8_t transponderIrDataTransferInProgress = 0; -void transponderDMAHandler(DMA_Channel_TypeDef *channel) +void transponderDMAHandler(dmaChannelDescriptor_t* descriptor) { - if (DMA_GetFlagStatus(TRANSPONDER_DMA_TC_FLAG)) { + if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) { transponderIrDataTransferInProgress = 0; - DMA_Cmd(channel, DISABLE); - DMA_ClearFlag(TRANSPONDER_DMA_TC_FLAG); + DMA_Cmd(descriptor->channel, DISABLE); + DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); } } void transponderIrInit(void) { memset(&transponderIrDMABuffer, 0, TRANSPONDER_DMA_BUFFER_SIZE); - dmaSetHandler(TRANSPONDER_DMA_HANDLER_IDENTIFER, transponderDMAHandler); + dmaSetHandler(TRANSPONDER_DMA_HANDLER_IDENTIFER, transponderDMAHandler, NVIC_PRIO_TRANSPONDER_DMA, 0); transponderIrHardwareInit(); } diff --git a/src/main/drivers/transponder_ir_stm32f30x.c b/src/main/drivers/transponder_ir_stm32f30x.c index d41e3aa8c8..3962e1c999 100644 --- a/src/main/drivers/transponder_ir_stm32f30x.c +++ b/src/main/drivers/transponder_ir_stm32f30x.c @@ -86,7 +86,7 @@ void transponderIrHardwareInit(void) /* configure DMA */ /* DMA clock enable */ - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); + //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* DMA1 Channel6 Config */ DMA_DeInit(TRANSPONDER_DMA_CHANNEL); @@ -110,13 +110,6 @@ void transponderIrHardwareInit(void) DMA_ITConfig(TRANSPONDER_DMA_CHANNEL, DMA_IT_TC, ENABLE); - NVIC_InitTypeDef NVIC_InitStructure; - - NVIC_InitStructure.NVIC_IRQChannel = TRANSPONDER_IRQ; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_TRANSPONDER_DMA); - NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_TRANSPONDER_DMA); - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); } void transponderIrDMAEnable(void) diff --git a/src/main/target/OMNIBUS/target.h b/src/main/target/OMNIBUS/target.h index c9eb4a59da..a7c09026a3 100644 --- a/src/main/target/OMNIBUS/target.h +++ b/src/main/target/OMNIBUS/target.h @@ -125,7 +125,9 @@ #define USE_MAX7456 #define MAX7456_SPI_INSTANCE SPI1 #define MAX7456_SPI_CS_PIN SPI1_NSS_PIN - +#define MAX7456_DMA_CHANNEL_TX DMA1_Channel3 +//#define MAX7456_DMA_CHANNEL_RX DMA1_Channel2 // <- Conflicts with WS2811 DMA +#define MAX7456_DMA_IRQ_HANDLER_ID DMA1_CH3_HANDLER #define USE_SPI #define USE_SPI_DEVICE_2 // PB12,13,14,15 on AF5 diff --git a/src/main/target/SIRINFPV/target.h b/src/main/target/SIRINFPV/target.h index cf6eacf4cb..76ca16fe9f 100644 --- a/src/main/target/SIRINFPV/target.h +++ b/src/main/target/SIRINFPV/target.h @@ -114,10 +114,7 @@ #define MAX7456_DMA_CHANNEL_TX DMA2_Channel2 #define MAX7456_DMA_CHANNEL_RX DMA2_Channel1 -#define MAX7456_DMA_TC_FLAG DMA2_FLAG_TC1 -#define MAX7456_DMA_PERIPH_CLOCK RCC_AHBPeriph_DMA2 -#define MAX7456_DMA_IRQ_HANDLER_FUNCTION DMA2_Channel1_IRQHandler -#define MAX7456_DMA_IRQ_HANDLER_ID DMA2_Channel1_IRQn +#define MAX7456_DMA_IRQ_HANDLER_ID DMA2_CH1_HANDLER #define USE_RTC6705 #define RTC6705_SPIDATA_PIN PC15 From 801add3ce39a3a3a3174c0abef0623b918c3d8fb Mon Sep 17 00:00:00 2001 From: Evgeny Sychov Date: Sat, 2 Jul 2016 17:14:08 -0700 Subject: [PATCH 4/6] Fix F4 targets --- src/main/drivers/dma.h | 3 +-- src/main/drivers/dma_stm32f4xx.c | 29 ++++++++++++------------ src/main/drivers/serial_uart_stm32f4xx.c | 5 ++-- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/main/drivers/dma.h b/src/main/drivers/dma.h index 345c7b2ed8..e0bbdfd12b 100644 --- a/src/main/drivers/dma.h +++ b/src/main/drivers/dma.h @@ -20,7 +20,6 @@ struct dmaChannelDescriptor_s; typedef void (*dmaCallbackHandlerFuncPtr)(struct dmaChannelDescriptor_s *channelDescriptor); #ifdef STM32F4 -typedef void(*dmaCallbackHandlerFuncPtr)(DMA_Stream_TypeDef *stream); typedef enum { DMA1_ST1_HANDLER = 0, @@ -55,7 +54,7 @@ typedef struct dmaChannelDescriptor_s { dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\ } -#define DMA_CLEAR_FLAG(d, flag) d->flagsShift > 31 ? d->dma->HIFCR = (flag << (d->flagsShift - 32)) : d->dma->LIFCR = (flag << d->flagsShift) +#define DMA_CLEAR_FLAG(d, flag) if(d->flagsShift > 31) d->dma->HIFCR = (flag << (d->flagsShift - 32)); else d->dma->LIFCR = (flag << d->flagsShift) #define DMA_GET_FLAG_STATUS(d, flag) (d->flagsShift > 31 ? d->dma->HISR & (flag << (d->flagsShift - 32)): d->dma->LISR & (flag << d->flagsShift)) diff --git a/src/main/drivers/dma_stm32f4xx.c b/src/main/drivers/dma_stm32f4xx.c index 3f57dfd985..4661864867 100644 --- a/src/main/drivers/dma_stm32f4xx.c +++ b/src/main/drivers/dma_stm32f4xx.c @@ -53,18 +53,18 @@ static dmaChannelDescriptor_t dmaDescriptors[] = { /* * DMA IRQ Handlers */ -DEFINE_DMA_IRQ_HANDLER(1, 1, DMA1_CH1_HANDLER) -DEFINE_DMA_IRQ_HANDLER(1, 2, DMA1_CH2_HANDLER) -DEFINE_DMA_IRQ_HANDLER(1, 3, DMA1_CH3_HANDLER) -DEFINE_DMA_IRQ_HANDLER(1, 4, DMA1_CH4_HANDLER) -DEFINE_DMA_IRQ_HANDLER(1, 5, DMA1_CH5_HANDLER) -DEFINE_DMA_IRQ_HANDLER(1, 6, DMA1_CH6_HANDLER) -DEFINE_DMA_IRQ_HANDLER(1, 7, DMA1_CH7_HANDLER) -DEFINE_DMA_IRQ_HANDLER(2, 1, DMA2_CH1_HANDLER) -DEFINE_DMA_IRQ_HANDLER(2, 2, DMA2_CH2_HANDLER) -DEFINE_DMA_IRQ_HANDLER(2, 3, DMA2_CH3_HANDLER) -DEFINE_DMA_IRQ_HANDLER(2, 4, DMA2_CH4_HANDLER) -DEFINE_DMA_IRQ_HANDLER(2, 5, DMA2_CH5_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 1, DMA1_ST1_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 2, DMA1_ST2_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 3, DMA1_ST3_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 4, DMA1_ST4_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 5, DMA1_ST5_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 6, DMA1_ST6_HANDLER) +DEFINE_DMA_IRQ_HANDLER(1, 7, DMA1_ST7_HANDLER) +DEFINE_DMA_IRQ_HANDLER(2, 1, DMA2_ST1_HANDLER) +DEFINE_DMA_IRQ_HANDLER(2, 2, DMA2_ST2_HANDLER) +DEFINE_DMA_IRQ_HANDLER(2, 3, DMA2_ST3_HANDLER) +DEFINE_DMA_IRQ_HANDLER(2, 4, DMA2_ST4_HANDLER) +DEFINE_DMA_IRQ_HANDLER(2, 5, DMA2_ST5_HANDLER) void dmaInit(void) @@ -72,12 +72,13 @@ void dmaInit(void) // TODO: Do we need this? } -void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority) +void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam) { NVIC_InitTypeDef NVIC_InitStructure; - RCC_AHB1PeriphClockCmd(dmaDescriptors[identifier].periphClk, ENABLE); + RCC_AHB1PeriphClockCmd(dmaDescriptors[identifier].rrc, ENABLE); dmaDescriptors[identifier].irqHandlerCallback = callback; + dmaDescriptors[identifier].userParam = userParam; NVIC_InitStructure.NVIC_IRQChannel = dmaDescriptors[identifier].irqN; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(priority); diff --git a/src/main/drivers/serial_uart_stm32f4xx.c b/src/main/drivers/serial_uart_stm32f4xx.c index d8c8ee5df5..4d9bf82dbd 100644 --- a/src/main/drivers/serial_uart_stm32f4xx.c +++ b/src/main/drivers/serial_uart_stm32f4xx.c @@ -25,6 +25,7 @@ #include "io.h" #include "rcc.h" #include "nvic.h" +#include "dma.h" #include "serial.h" #include "serial_uart.h" @@ -278,9 +279,9 @@ static void handleUsartTxDma(uartPort_t *s) s->txDMAEmpty = true; } -void dmaIRQHandler(dmaChannelDescriptor_t descriptor) +void dmaIRQHandler(dmaChannelDescriptor_t* descriptor) { - uartPort_t *s = &((uartDevice_t*)(descriptor->userParam)->port); + uartPort_t *s = &(((uartDevice_t*)(descriptor->userParam))->port); if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) { DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); From 325f4297cc33b051754f4508729ecc3e34087ac9 Mon Sep 17 00:00:00 2001 From: Evgeny Sychov Date: Sun, 3 Jul 2016 03:49:39 -0700 Subject: [PATCH 5/6] Fix typo - replace rrc by rcc --- src/main/drivers/dma.c | 2 +- src/main/drivers/dma.h | 8 ++++---- src/main/drivers/dma_stm32f4xx.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/drivers/dma.c b/src/main/drivers/dma.c index cbcaa5eafb..4b6cace0e5 100644 --- a/src/main/drivers/dma.c +++ b/src/main/drivers/dma.c @@ -75,7 +75,7 @@ void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr { NVIC_InitTypeDef NVIC_InitStructure; - RCC_AHBPeriphClockCmd(dmaDescriptors[identifier].rrc, ENABLE); + RCC_AHBPeriphClockCmd(dmaDescriptors[identifier].rcc, ENABLE); dmaDescriptors[identifier].irqHandlerCallback = callback; dmaDescriptors[identifier].userParam = userParam; diff --git a/src/main/drivers/dma.h b/src/main/drivers/dma.h index e0bbdfd12b..4f0dabdfff 100644 --- a/src/main/drivers/dma.h +++ b/src/main/drivers/dma.h @@ -44,11 +44,11 @@ typedef struct dmaChannelDescriptor_s { dmaCallbackHandlerFuncPtr irqHandlerCallback; uint8_t flagsShift; IRQn_Type irqN; - uint32_t rrc; + uint32_t rcc; uint32_t userParam; } dmaChannelDescriptor_t; -#define DEFINE_DMA_CHANNEL(d, s, f, i, r) {.dma = d, .stream = s, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rrc = r, .userParam = 0} +#define DEFINE_DMA_CHANNEL(d, s, f, i, r) {.dma = d, .stream = s, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rcc = r, .userParam = 0} #define DEFINE_DMA_IRQ_HANDLER(d, s, i) void DMA ## d ## _Stream ## s ## _IRQHandler(void) {\ if (dmaDescriptors[i].irqHandlerCallback)\ dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\ @@ -87,11 +87,11 @@ typedef struct dmaChannelDescriptor_s { dmaCallbackHandlerFuncPtr irqHandlerCallback; uint8_t flagsShift; IRQn_Type irqN; - uint32_t rrc; + uint32_t rcc; uint32_t userParam; } dmaChannelDescriptor_t; -#define DEFINE_DMA_CHANNEL(d, c, f, i, r) {.dma = d, .channel = c, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rrc = r, .userParam = 0} +#define DEFINE_DMA_CHANNEL(d, c, f, i, r) {.dma = d, .channel = c, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rcc = r, .userParam = 0} #define DEFINE_DMA_IRQ_HANDLER(d, c, i) void DMA ## d ## _Channel ## c ## _IRQHandler(void) {\ if (dmaDescriptors[i].irqHandlerCallback)\ dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\ diff --git a/src/main/drivers/dma_stm32f4xx.c b/src/main/drivers/dma_stm32f4xx.c index 4661864867..bf2d2ec582 100644 --- a/src/main/drivers/dma_stm32f4xx.c +++ b/src/main/drivers/dma_stm32f4xx.c @@ -76,7 +76,7 @@ void dmaSetHandler(dmaHandlerIdentifier_e identifier, dmaCallbackHandlerFuncPtr { NVIC_InitTypeDef NVIC_InitStructure; - RCC_AHB1PeriphClockCmd(dmaDescriptors[identifier].rrc, ENABLE); + RCC_AHB1PeriphClockCmd(dmaDescriptors[identifier].rcc, ENABLE); dmaDescriptors[identifier].irqHandlerCallback = callback; dmaDescriptors[identifier].userParam = userParam; From 95a22053d71b6f68e15d0a77ce22e1c7e822c7a1 Mon Sep 17 00:00:00 2001 From: Evgeny Sychov Date: Sat, 9 Jul 2016 20:28:18 -0700 Subject: [PATCH 6/6] avoid warnings --- src/main/drivers/serial_uart_stm32f10x.c | 2 +- src/main/drivers/serial_uart_stm32f30x.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/drivers/serial_uart_stm32f10x.c b/src/main/drivers/serial_uart_stm32f10x.c index 4cf886d075..330b3f837a 100644 --- a/src/main/drivers/serial_uart_stm32f10x.c +++ b/src/main/drivers/serial_uart_stm32f10x.c @@ -139,7 +139,7 @@ uartPort_t *serialUART1(uint32_t baudRate, portMode_t mode, portOptions_t option } // DMA TX Interrupt - dmaSetHandler(DMA1_CH4_HANDLER, uart_tx_dma_IRQHandler, NVIC_PRIO_SERIALUART1_TXDMA, &uartPort1); + dmaSetHandler(DMA1_CH4_HANDLER, uart_tx_dma_IRQHandler, NVIC_PRIO_SERIALUART1_TXDMA, (uint32_t)&uartPort1); #ifndef USE_UART1_RX_DMA // RX/TX Interrupt diff --git a/src/main/drivers/serial_uart_stm32f30x.c b/src/main/drivers/serial_uart_stm32f30x.c index f586ee5276..ee65d54d2d 100644 --- a/src/main/drivers/serial_uart_stm32f30x.c +++ b/src/main/drivers/serial_uart_stm32f30x.c @@ -171,7 +171,7 @@ uartPort_t *serialUART1(uint32_t baudRate, portMode_t mode, portOptions_t option serialUARTInit(IOGetByTag(IO_TAG(UART1_TX_PIN)), IOGetByTag(IO_TAG(UART1_RX_PIN)), mode, options, GPIO_AF_7, 1); - dmaSetHandler(DMA1_CH4_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART1_TXDMA, &uartPort1); + dmaSetHandler(DMA1_CH4_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART1_TXDMA, (uint32_t)&uartPort1); #ifndef USE_UART1_RX_DMA NVIC_InitTypeDef NVIC_InitStructure; @@ -225,7 +225,7 @@ uartPort_t *serialUART2(uint32_t baudRate, portMode_t mode, portOptions_t option #ifdef USE_UART2_TX_DMA // DMA TX Interrupt - dmaSetHandler(DMA1_CH7_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART2_TXDMA, &uartPort2); + dmaSetHandler(DMA1_CH7_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART2_TXDMA, (uint32_t)&uartPort2); #endif #ifndef USE_UART2_RX_DMA @@ -280,7 +280,7 @@ uartPort_t *serialUART3(uint32_t baudRate, portMode_t mode, portOptions_t option #ifdef USE_UART3_TX_DMA // DMA TX Interrupt - dmaSetHandler(DMA1_CH2_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART3_TXDMA, &uartPort3); + dmaSetHandler(DMA1_CH2_HANDLER, handleUsartTxDma, NVIC_PRIO_SERIALUART3_TXDMA, (uint32_t)&uartPort3); #endif #ifndef USE_UART3_RX_DMA