++
Fork of mbed-stm32l0/l1-src by
Revision 593:78ee8643776a, committed 2015-07-20
- Comitter:
- mbed_official
- Date:
- Mon Jul 20 09:00:09 2015 +0100
- Parent:
- 592:a274ee790e56
- Child:
- 594:5afbce4ea2da
- Commit message:
- Synchronized with git revision a68b724d07788e6389ea4d52c622aad767953758
Full URL: https://github.com/mbedmicro/mbed/commit/a68b724d07788e6389ea4d52c622aad767953758/
[Silicon Labs] Bring EFM32 HAL up to date
Changed in this revision
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/TOOLCHAIN_ARM_MICRO/startup_efm32gg.S Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/TOOLCHAIN_ARM_MICRO/startup_efm32gg.S Mon Jul 20 09:00:09 2015 +0100 @@ -33,7 +33,7 @@ AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size -__initial_sp +__initial_sp EQU 0x20020000 ; <h> Heap Configuration
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/TOOLCHAIN_ARM_STD/startup_efm32gg.S Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/TOOLCHAIN_ARM_STD/startup_efm32gg.S Mon Jul 20 09:00:09 2015 +0100 @@ -33,7 +33,7 @@ AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size -__initial_sp +__initial_sp EQU 0x20020000 ; <h> Heap Configuration
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_ARM_MICRO/efm32hg.sct Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_ARM_MICRO/efm32hg.sct Mon Jul 20 09:00:09 2015 +0100 @@ -8,7 +8,7 @@ *(InRoot$$Sections) .ANY (+RO) } - RW_IRAM1 0x20000080 0x00001F80 { ; RW data + RW_IRAM1 0x20000098 0x00001F68 { ; RW data .ANY (+RW +ZI) } }
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_ARM_MICRO/startup_efm32hg.S Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_ARM_MICRO/startup_efm32hg.S Mon Jul 20 09:00:09 2015 +0100 @@ -33,7 +33,7 @@ AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size -__initial_sp +__initial_sp EQU 0x20002000 ; <h> Heap Configuration
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_GCC_ARM/efm32hg.ld Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/TOOLCHAIN_GCC_ARM/efm32hg.ld Mon Jul 20 09:00:09 2015 +0100 @@ -16,8 +16,8 @@ /* MBED: mbed needs to be able to dynamically set the interrupt vector table. * We make room for the table at the very beginning of RAM, i.e. at - * 0x20000000. We need (16+20) * sizeof(uint32_t) = 144 bytes for EFM32HG */ -__vector_size = 0x90; + * 0x20000000. We need (16+21) * sizeof(uint32_t) = 144 bytes for EFM32HG */ +__vector_size = 0x94; /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM.
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/cmsis_nvic.h Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/cmsis_nvic.h Mon Jul 20 09:00:09 2015 +0100 @@ -9,7 +9,7 @@ #include "cmsis.h" -#define NVIC_NUM_VECTORS (16 + 16) // CORE + MCU Peripherals +#define NVIC_NUM_VECTORS (16 + 21) // CORE + MCU Peripherals #define NVIC_USER_IRQ_OFFSET 16 #ifdef __cplusplus
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/TOOLCHAIN_ARM_MICRO/startup_efm32lg.S Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/TOOLCHAIN_ARM_MICRO/startup_efm32lg.S Mon Jul 20 09:00:09 2015 +0100 @@ -33,7 +33,7 @@ AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size -__initial_sp +__initial_sp EQU 0x20008000 ; <h> Heap Configuration
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/TOOLCHAIN_ARM_STD/startup_efm32lg.S Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/TOOLCHAIN_ARM_STD/startup_efm32lg.S Mon Jul 20 09:00:09 2015 +0100 @@ -33,7 +33,7 @@ AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size -__initial_sp +__initial_sp EQU 0x20008000 ; <h> Heap Configuration
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/TOOLCHAIN_ARM_MICRO/startup_efm32wg.S Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/TOOLCHAIN_ARM_MICRO/startup_efm32wg.S Mon Jul 20 09:00:09 2015 +0100 @@ -33,7 +33,7 @@ AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size -__initial_sp +__initial_sp EQU 0x20008000 ; <h> Heap Configuration
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/TOOLCHAIN_ARM_STD/startup_efm32wg.S Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/TOOLCHAIN_ARM_STD/startup_efm32wg.S Mon Jul 20 09:00:09 2015 +0100 @@ -33,7 +33,7 @@ AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size -__initial_sp +__initial_sp EQU 0x20008000 ; <h> Heap Configuration
--- a/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/TOOLCHAIN_ARM_MICRO/startup_efm32zg.S Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/TOOLCHAIN_ARM_MICRO/startup_efm32zg.S Mon Jul 20 09:00:09 2015 +0100 @@ -33,7 +33,7 @@ AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size -__initial_sp +__initial_sp EQU 0x20001000 ; <h> Heap Configuration
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/PinNames.h Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32GG_STK3700/PinNames.h Mon Jul 20 09:00:09 2015 +0100 @@ -103,7 +103,7 @@ PullDown = InputPullDown, OpenDrain = WiredAnd, PullNone = PushPull, - PullDefault = PullUp + PullDefault = PushPull } PinMode; #ifdef __cplusplus
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/PinNames.h Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/PinNames.h Mon Jul 20 09:00:09 2015 +0100 @@ -102,7 +102,7 @@ PullDown = InputPullDown, OpenDrain = WiredAnd, PullNone = PushPull, - PullDefault = PullUp + PullDefault = PushPull } PinMode; #ifdef __cplusplus
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/PinNames.h Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32LG_STK3600/PinNames.h Mon Jul 20 09:00:09 2015 +0100 @@ -102,7 +102,7 @@ PullDown = InputPullDown, OpenDrain = WiredAnd, PullNone = PushPull, - PullDefault = PullUp + PullDefault = PushPull } PinMode; #ifdef __cplusplus
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/PinNames.h Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32WG_STK3800/PinNames.h Mon Jul 20 09:00:09 2015 +0100 @@ -102,7 +102,7 @@ PullDown = InputPullDown, OpenDrain = WiredAnd, PullNone = PushPull, - PullDefault = PullUp + PullDefault = PushPull } PinMode; #ifdef __cplusplus
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/PinNames.h Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/PinNames.h Mon Jul 20 09:00:09 2015 +0100 @@ -102,7 +102,7 @@ PullDown = InputPullDown, OpenDrain = WiredAnd, PullNone = PushPull, - PullDefault = PullUp + PullDefault = PushPull } PinMode; #ifdef __cplusplus
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_api.c Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_api.c Mon Jul 20 09:00:09 2015 +0100 @@ -19,9 +19,28 @@ #include "mbed_assert.h" #include "sleepmodes.h" -uint8_t gpio_get_index(gpio_t *obj) + +void gpio_write(gpio_t *obj, int value) { - return 0; + if (value) { + GPIO_PinOutSet((GPIO_Port_TypeDef)(obj->pin >> 4 & 0xF), obj->pin & 0xF); // Pin number encoded in first four bits of obj->pin + } else { + GPIO_PinOutClear((GPIO_Port_TypeDef)(obj->pin >> 4 & 0xF), obj->pin & 0xF); + } +} + +int gpio_read(gpio_t *obj) +{ + if (obj->dir == PIN_INPUT) { + return GPIO_PinInGet((GPIO_Port_TypeDef)(obj->pin >> 4 & 0xF), obj->pin & 0xF); // Pin number encoded in first four bits of obj->pin + } else { + return GPIO_PinOutGet((GPIO_Port_TypeDef)(obj->pin >> 4 & 0xF), obj->pin & 0xF); + } +} + +int gpio_is_connected(const gpio_t *obj) +{ + return (obj->pin | 0xFFFFFF00 )!= (PinName)NC; } /* @@ -44,25 +63,49 @@ obj->pin = pin; } -void gpio_pin_enable(gpio_t *obj, uint8_t enable) -{ - if (enable) { - pin_mode(obj->pin, obj->mode); - } else { - pin_mode(obj->pin, Disabled); // TODO_LP return mode to default value - } -} - void gpio_mode(gpio_t *obj, PinMode mode) { + if(obj->dir == PIN_INPUT) { + switch(mode) { + case PullDefault: + mode = Input; + break; + case PullUp: + mode = InputPullUp; + break; + case PullDown: + mode = InputPullDown; + break; + default: + break; + } + + //Handle DOUT setting + if((mode & 0x10) != 0) { + //Set DOUT + GPIO->P[(obj->pin >> 4) & 0xF].DOUTSET = 1 << (obj->pin & 0xF); + } else { + //Clear DOUT + GPIO->P[(obj->pin >> 4) & 0xF].DOUTCLR = 1 << (obj->pin & 0xF); + } + } else { + switch(mode) { + case PullDefault: + mode = PushPull; + break; + case PullUp: + mode = WiredAndPullUp; + break; + case PullDown: + mode = WiredOrPullDown; + break; + default: + break; + } + } + obj->mode = mode; // Update object pin_mode(obj->pin, mode); // Update register - - //Handle pullup for input - if(mode == InputPullUp) { - //Set DOUT - GPIO->P[(obj->pin >> 4) & 0xF].DOUTSET = 1 << (obj->pin & 0xF); - } } // Used by DigitalInOut to set correct mode when direction is set @@ -78,4 +121,3 @@ break; } } -
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_irq_api.c Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_irq_api.c Mon Jul 20 09:00:09 2015 +0100 @@ -46,7 +46,7 @@ #endif static uint32_t channel_ids[NUM_GPIO_CHANNELS] = { 0 }; // Relates pin number with interrupt action id -static uint32_t channel_ports[NUM_GPIO_CHANNELS] = { 0 }; +static uint8_t channel_ports[NUM_GPIO_CHANNELS/2] = { 0 }; // Storing 2 ports in each uint8 static gpio_irq_handler irq_handler; static void GPIOINT_IRQDispatcher(uint32_t iflags); @@ -57,7 +57,9 @@ return; } - uint32_t isRise = GPIO_PinInGet(channel_ports[pin], pin); + //we are storing two ports in each uint8, so we must aquire the one we want. + // If pin is odd, the port is encoded in the 4 most significant bits. If pin is even, the port is encoded in the 4 least significant bits + uint8_t isRise = GPIO_PinInGet((pin & 0x1) ? channel_ports[(pin>>1) & 0x7] >> 4 & 0xF : channel_ports[(pin>>1) & 0x7] & 0xF, pin); // Get trigger event gpio_irq_event event = IRQ_NONE; @@ -77,40 +79,39 @@ /* Pin and port index encoded in one uint32. * The four least significant bits represent the pin number * The remaining bits represent the port number */ - obj->pin = pin & 0xF; - obj->port = pin >> 4; + obj->pin = pin; obj->risingEdge = 0; obj->fallingEdge = 0; } int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { - /* Init pins */ + // Init pins gpio_irq_preinit(obj, pin); - /* Initialize GPIO interrupt dispatcher */ + // Initialize GPIO interrupt dispatcher NVIC_ClearPendingIRQ(GPIO_ODD_IRQn); NVIC_EnableIRQ(GPIO_ODD_IRQn); NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn); NVIC_EnableIRQ(GPIO_EVEN_IRQn); /* Relate pin to interrupt action id */ - channel_ids[obj->pin] = id; - /* Relate the pin number to a port */ - channel_ports[obj->pin] = obj->port; + channel_ids[obj->pin & 0xF] = id; + + // Relate the pin number to a port. If pin in is odd store in the 4 most significant bits, if pin is even store in the 4 least significant bits + channel_ports[(obj->pin >> 1) & 0x7] = (obj->pin & 0x1) ? (channel_ports[(obj->pin >> 1) & 0x7] & 0x0F) | (obj->pin & 0xF0) : (channel_ports[(obj->pin >> 1) & 0x7] & 0xF0) | ((obj->pin >> 4) & 0xF); /* Save pointer to handler */ irq_handler = handler; - pin_mode(obj->pin | (obj->port << 4), Input); - + pin_mode(obj->pin, Input); return 0; } void gpio_irq_free(gpio_irq_t *obj) { // Destructor - channel_ids[obj->pin] = 0; + channel_ids[obj->pin & 0xF] = 0; gpio_irq_disable(obj); // Disable interrupt channel - pin_mode(obj->pin | (obj->port << 4), Disabled); // Disable input pin + pin_mode(obj->pin, Disabled); // Disable input pin } void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) @@ -132,7 +133,7 @@ bool was_disabled = false; if(GPIO->IEN == 0) was_disabled = true; - GPIO_IntConfig(obj->port, obj->pin, obj->risingEdge, obj->fallingEdge, obj->risingEdge || obj->fallingEdge); + GPIO_IntConfig((GPIO_Port_TypeDef)(obj->pin >> 4 & 0xF), obj->pin &0xF, obj->risingEdge, obj->fallingEdge, obj->risingEdge || obj->fallingEdge); if ((GPIO->IEN != 0) && (obj->risingEdge || obj->fallingEdge) && was_disabled) { blockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE); } @@ -141,12 +142,12 @@ inline void gpio_irq_enable(gpio_irq_t *obj) { if(GPIO->IEN == 0) blockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE); - GPIO_IntEnable(1 << obj->pin); // pin mask for pins to enable + GPIO_IntEnable(1 << obj->pin & 0xF); // pin mask for pins to enable } inline void gpio_irq_disable(gpio_irq_t *obj) { - GPIO_IntDisable(1 << obj->pin); // pin mask for pins to disable + GPIO_IntDisable(1 << obj->pin & 0xF); // pin mask for pins to disable if(GPIO->IEN == 0) unblockSleepMode(GPIO_LEAST_ACTIVE_SLEEPMODE); } @@ -171,7 +172,7 @@ while(iflags) { irqIdx = GPIOINT_MASK2IDX(iflags); - /* clear flag*/ + /* clear flag */ iflags &= ~(1 << irqIdx); /* call user callback */ @@ -188,13 +189,12 @@ void GPIO_EVEN_IRQHandler(void) { uint32_t iflags; - - /* Get all even interrupts. */ + /* Get all even interrupts */ iflags = GPIO_IntGetEnabled() & 0x00005555; - /* Clean only even interrupts. */ + /* Clean only even interrupts*/ + GPIO_IntClear(iflags); - GPIOINT_IRQDispatcher(iflags); } @@ -209,12 +209,11 @@ { uint32_t iflags; - /* Get all odd interrupts. */ + /* Get all odd interrupts */ iflags = GPIO_IntGetEnabled() & 0x0000AAAA; - /* Clean only even interrupts. */ + /* Clean only even interrupts */ GPIO_IntClear(iflags); - GPIOINT_IRQDispatcher(iflags); }
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/gpio_object.h Fri Jul 17 09:15:10 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef MBED_GPIO_OBJECT_H -#define MBED_GPIO_OBJECT_H - -#include "em_gpio.h" -#include "PinNames.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - PinName pin; - PinMode mode; - PinDirection dir; -} gpio_t; - -static inline void gpio_write(gpio_t *obj, int value) -{ - if (value) { - GPIO_PinOutSet((GPIO_Port_TypeDef)((obj->pin >> 4) & 0xF), obj->pin & 0xF); // Pin number encoded in first four bits of obj->pin - } else { - GPIO_PinOutClear((GPIO_Port_TypeDef)((obj->pin >> 4) & 0xF), obj->pin & 0xF); - } -} - -static inline int gpio_read(gpio_t *obj) -{ - if (obj->dir == PIN_INPUT) { - return GPIO_PinInGet((GPIO_Port_TypeDef)((obj->pin >> 4) & 0xF), obj->pin & 0xF); // Pin number encoded in first four bits of obj->pin - } else { - return GPIO_PinOutGet((GPIO_Port_TypeDef)((obj->pin >> 4) & 0xF), obj->pin & 0xF); - } -} - -static inline int gpio_is_connected(const gpio_t *obj) -{ - return obj->pin != (PinName)NC; -} - -#ifdef __cplusplus -} -#endif - -#endif
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/objects.h Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/objects.h Mon Jul 20 09:00:09 2015 +0100 @@ -28,6 +28,12 @@ extern "C" { #endif +typedef struct { + PinName pin:8; + PinMode mode:6; + PinDirection dir:2; +} gpio_t; + #if DEVICE_ANALOGIN struct analogin_s { ADC_TypeDef *adc; @@ -79,10 +85,9 @@ #if DEVICE_INTERRUPTIN struct gpio_irq_s { - uint32_t port; - PinName pin; - uint32_t risingEdge; - uint32_t fallingEdge; + PinName pin:8; // Pin number 4 least significant bits, port number 4 most significant bits + uint32_t risingEdge:1; + uint32_t fallingEdge:1; }; #endif @@ -137,7 +142,6 @@ } sleepstate_enum; #endif -#include "gpio_object.h" #ifdef __cplusplus }
--- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/spi_api.c Fri Jul 17 09:15:10 2015 +0100 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/spi_api.c Mon Jul 20 09:00:09 2015 +0100 @@ -977,7 +977,7 @@ /* If there is still data in the TX buffer, setup a new transfer. */ if (obj->tx_buff.pos < obj->tx_buff.length) { /* Find position and remaining length without modifying tx_buff. */ - void* tx_pointer = obj->tx_buff.buffer + obj->tx_buff.pos; + void* tx_pointer = (char*)obj->tx_buff.buffer + obj->tx_buff.pos; uint32_t tx_length = obj->tx_buff.length - obj->tx_buff.pos; /* Begin transfer. Rely on spi_activate_dma to split up the transfer further. */