From 78767491f72e04070af922110ed6f8a291aec751 Mon Sep 17 00:00:00 2001 From: Bartosz Szczepanski Date: Tue, 19 Apr 2016 16:38:14 +0200 Subject: [PATCH 01/87] Added CAN API for STM32F3xx family * STM32F3xx family have only one CAN bus Change-Id: Icaed8ff8ca4a68ebbf2c124655e7368423fb71cd --- .../TARGET_STM32F3/PeripheralPins.h | 4 + .../hal/TARGET_STM/TARGET_STM32F3/can_api.c | 479 ++++++++++++++++++ 2 files changed, 483 insertions(+) create mode 100644 hal/targets/hal/TARGET_STM/TARGET_STM32F3/can_api.c diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/PeripheralPins.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/PeripheralPins.h index cc2fcaaf114..e6077cf110d 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/PeripheralPins.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/PeripheralPins.h @@ -63,4 +63,8 @@ extern const PinMap PinMap_SPI_MISO[]; extern const PinMap PinMap_SPI_SCLK[]; extern const PinMap PinMap_SPI_SSEL[]; +//*** CAN *** +extern const PinMap PinMap_CAN_RD[]; +extern const PinMap PinMap_CAN_TD[]; + #endif diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/can_api.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/can_api.c new file mode 100644 index 00000000000..a0416a61c40 --- /dev/null +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/can_api.c @@ -0,0 +1,479 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2016 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. + */ +#include "can_api.h" + +#if DEVICE_CAN + +#include "cmsis.h" +#include "pinmap.h" +#include "PeripheralPins.h" +#include "mbed_error.h" +#include +#include + +#define CAN_NUM 1 +static CAN_HandleTypeDef CanHandle; +static uint32_t can_irq_ids[CAN_NUM] = {0}; +static can_irq_handler irq_handler; + +void can_init(can_t *obj, PinName rd, PinName td) +{ + CANName can_rd = (CANName)pinmap_peripheral(rd, PinMap_CAN_RD); + CANName can_td = (CANName)pinmap_peripheral(td, PinMap_CAN_TD); + obj->can = (CANName)pinmap_merge(can_rd, can_td); + MBED_ASSERT((int)obj->can != NC); + + if(obj->can == CAN_1) { + __CAN_CLK_ENABLE(); + obj->index = 0; + } + + // Configure the CAN pins + pinmap_pinout(rd, PinMap_CAN_RD); + pinmap_pinout(td, PinMap_CAN_TD); + if (rd != NC) { + pin_mode(rd, PullUp); + } + if (td != NC) { + pin_mode(td, PullUp); + } + + CanHandle.Instance = (CAN_TypeDef *)(obj->can); + + CanHandle.Init.TTCM = DISABLE; + CanHandle.Init.ABOM = DISABLE; + CanHandle.Init.AWUM = DISABLE; + CanHandle.Init.NART = DISABLE; + CanHandle.Init.RFLM = DISABLE; + CanHandle.Init.TXFP = DISABLE; + CanHandle.Init.Mode = CAN_MODE_NORMAL; + CanHandle.Init.SJW = CAN_SJW_1TQ; + CanHandle.Init.BS1 = CAN_BS1_6TQ; + CanHandle.Init.BS2 = CAN_BS2_8TQ; + CanHandle.Init.Prescaler = 2; + + if (HAL_CAN_Init(&CanHandle) != HAL_OK) { + error("Cannot initialize CAN"); + } + // Set initial CAN frequency to 100kb/s + can_frequency(obj, 100000); + + can_filter(obj, 0, 0, CANStandard, 0); +} + +void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) +{ + irq_handler = handler; + can_irq_ids[obj->index] = id; +} + +void can_irq_free(can_t *obj) +{ + CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + + can->IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \ + CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF); + can_irq_ids[obj->can] = 0; +} + +void can_free(can_t *obj) +{ + // Reset CAN and disable clock + if (obj->can == CAN_1) { + __CAN_FORCE_RESET(); + __CAN_RELEASE_RESET(); + __CAN_CLK_DISABLE(); + } +} + +// The following table is used to program bit_timing. It is an adjustment of the sample +// point by synchronizing on the start-bit edge and resynchronizing on the following edges. +// This table has the sampling points as close to 75% as possible (most commonly used). +// The first value is TSEG1, the second TSEG2. +static const int timing_pts[23][2] = { + {0x0, 0x0}, // 2, 50% + {0x1, 0x0}, // 3, 67% + {0x2, 0x0}, // 4, 75% + {0x3, 0x0}, // 5, 80% + {0x3, 0x1}, // 6, 67% + {0x4, 0x1}, // 7, 71% + {0x5, 0x1}, // 8, 75% + {0x6, 0x1}, // 9, 78% + {0x6, 0x2}, // 10, 70% + {0x7, 0x2}, // 11, 73% + {0x8, 0x2}, // 12, 75% + {0x9, 0x2}, // 13, 77% + {0x9, 0x3}, // 14, 71% + {0xA, 0x3}, // 15, 73% + {0xB, 0x3}, // 16, 75% + {0xC, 0x3}, // 17, 76% + {0xD, 0x3}, // 18, 78% + {0xD, 0x4}, // 19, 74% + {0xE, 0x4}, // 20, 75% + {0xF, 0x4}, // 21, 76% + {0xF, 0x5}, // 22, 73% + {0xF, 0x6}, // 23, 70% + {0xF, 0x7}, // 24, 67% +}; + +static unsigned int can_speed(unsigned int pclk, unsigned int cclk, unsigned char psjw) +{ + uint32_t btr; + uint16_t brp = 0; + uint32_t calcbit; + uint32_t bitwidth; + int hit = 0; + int bits; + + bitwidth = (pclk / cclk); + + brp = bitwidth / 0x18; + while ((!hit) && (brp < bitwidth / 4)) { + brp++; + for (bits = 22; bits > 0; bits--) { + calcbit = (bits + 3) * (brp + 1); + if (calcbit == bitwidth) { + hit = 1; + break; + } + } + } + + if (hit) { + btr = ((timing_pts[bits][1] << 20) & 0x00700000) + | ((timing_pts[bits][0] << 16) & 0x000F0000) + | ((psjw << 24) & 0x0000C000) + | ((brp << 0) & 0x000003FF); + } else { + btr = 0xFFFFFFFF; + } + + return btr; + +} + +int can_frequency(can_t *obj, int f) +{ + int pclk = HAL_RCC_GetPCLK1Freq(); + int btr = can_speed(pclk, (unsigned int)f, 1); + CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + + if (btr > 0) { + can->MCR |= CAN_MCR_INRQ ; + while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { + } + can->BTR = btr; + can->MCR &= ~(uint32_t)CAN_MCR_INRQ; + while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { + } + return 1; + } else { + return 0; + } +} + +int can_write(can_t *obj, CAN_Message msg, int cc) +{ + uint32_t transmitmailbox = 5; + CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + + /* Select one empty transmit mailbox */ + if ((can->TSR&CAN_TSR_TME0) == CAN_TSR_TME0) { + transmitmailbox = 0; + } else if ((can->TSR&CAN_TSR_TME1) == CAN_TSR_TME1) { + transmitmailbox = 1; + } else if ((can->TSR&CAN_TSR_TME2) == CAN_TSR_TME2) { + transmitmailbox = 2; + } else { + transmitmailbox = CAN_TXSTATUS_NOMAILBOX; + } + + if (transmitmailbox != CAN_TXSTATUS_NOMAILBOX) { + can->sTxMailBox[transmitmailbox].TIR &= CAN_TI0R_TXRQ; + if (!(msg.format)) + { + can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 21) | msg.type); + } + else + { + can->sTxMailBox[transmitmailbox].TIR |= ((msg.id << 3) | CAN_ID_EXT | msg.type); + } + + /* Set up the DLC */ + can->sTxMailBox[transmitmailbox].TDTR &= (uint32_t)0xFFFFFFF0; + can->sTxMailBox[transmitmailbox].TDTR |= (msg.len & (uint8_t)0x0000000F); + + /* Set up the data field */ + can->sTxMailBox[transmitmailbox].TDLR = (((uint32_t)msg.data[3] << 24) | + ((uint32_t)msg.data[2] << 16) | + ((uint32_t)msg.data[1] << 8) | + ((uint32_t)msg.data[0])); + can->sTxMailBox[transmitmailbox].TDHR = (((uint32_t)msg.data[7] << 24) | + ((uint32_t)msg.data[6] << 16) | + ((uint32_t)msg.data[5] << 8) | + ((uint32_t)msg.data[4])); + /* Request transmission */ + can->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ; + } + + return 1; +} + +int can_read(can_t *obj, CAN_Message *msg, int handle) +{ + //handle is the FIFO number + + CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + + /* Get the Id */ + msg->format = (CANFormat)((uint8_t)0x04 & can->sFIFOMailBox[handle].RIR); + if (!msg->format) { + msg->id = (uint32_t)0x000007FF & (can->sFIFOMailBox[handle].RIR >> 21); + } else { + msg->id = (uint32_t)0x1FFFFFFF & (can->sFIFOMailBox[handle].RIR >> 3); + } + + msg->type = (CANType)((uint8_t)0x02 & can->sFIFOMailBox[handle].RIR); + /* Get the DLC */ + msg->len = (uint8_t)0x0F & can->sFIFOMailBox[handle].RDTR; +// /* Get the FMI */ +// msg->FMI = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDTR >> 8); + /* Get the data field */ + msg->data[0] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDLR; + msg->data[1] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 8); + msg->data[2] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 16); + msg->data[3] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDLR >> 24); + msg->data[4] = (uint8_t)0xFF & can->sFIFOMailBox[handle].RDHR; + msg->data[5] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 8); + msg->data[6] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 16); + msg->data[7] = (uint8_t)0xFF & (can->sFIFOMailBox[handle].RDHR >> 24); + + /* Release the FIFO */ + if(handle == CAN_FIFO0) { + /* Release FIFO0 */ + can->RF0R = CAN_RF0R_RFOM0; + } else { /* FIFONumber == CAN_FIFO1 */ + /* Release FIFO1 */ + can->RF1R = CAN_RF1R_RFOM1; + } + + return 1; +} + +void can_reset(can_t *obj) +{ + CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + + can->MCR |= CAN_MCR_RESET; + can->ESR = 0x0; +} + +unsigned char can_rderror(can_t *obj) +{ + CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + return (can->ESR >> 24) & 0xFF; +} + +unsigned char can_tderror(can_t *obj) +{ + CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + return (can->ESR >> 16) & 0xFF; +} + +void can_monitor(can_t *obj, int silent) +{ + CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + + can->MCR |= CAN_MCR_INRQ ; + while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { + } + if (silent) { + can->BTR |= ((uint32_t)1 << 31); + } else { + can->BTR &= ~((uint32_t)1 << 31); + } + can->MCR &= ~(uint32_t)CAN_MCR_INRQ; + while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { + } +} + +int can_mode(can_t *obj, CanMode mode) +{ + int success = 0; + CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + can->MCR |= CAN_MCR_INRQ ; + while((can->MSR & CAN_MSR_INAK) != CAN_MSR_INAK) { + } + switch (mode) { + case MODE_NORMAL: + can->BTR &= ~(CAN_BTR_SILM | CAN_BTR_LBKM); + success = 1; + break; + case MODE_SILENT: + can->BTR |= CAN_BTR_SILM; + can->BTR &= ~CAN_BTR_LBKM; + success = 1; + break; + case MODE_TEST_GLOBAL: + case MODE_TEST_LOCAL: + can->BTR |= CAN_BTR_LBKM; + can->BTR &= ~CAN_BTR_SILM; + success = 1; + break; + case MODE_TEST_SILENT: + can->BTR |= (CAN_BTR_SILM | CAN_BTR_LBKM); + success = 1; + break; + default: + success = 0; + break; + } + can->MCR &= ~(uint32_t)CAN_MCR_INRQ; + while((can->MSR & CAN_MSR_INAK) == CAN_MSR_INAK) { + } + return success; +} + +int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) +{ + CanHandle.Instance = (CAN_TypeDef *)(obj->can); + CAN_FilterConfTypeDef sFilterConfig; + + sFilterConfig.FilterNumber = handle; + sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; + sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; + sFilterConfig.FilterIdHigh = (uint8_t) (id >> 8); + sFilterConfig.FilterIdLow = (uint8_t) id; + sFilterConfig.FilterMaskIdHigh = (uint8_t) (mask >> 8); + sFilterConfig.FilterMaskIdLow = (uint8_t) mask; + sFilterConfig.FilterFIFOAssignment = 0; + sFilterConfig.FilterActivation = ENABLE; + sFilterConfig.BankNumber = 14 + handle; + + HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig); + + return 0; +} + +static void can_irq(CANName name, int id) +{ + uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0; + CanHandle.Instance = (CAN_TypeDef *)name; + + if(__HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_TME)) { + tmp1 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_0); + tmp2 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_1); + tmp3 = __HAL_CAN_TRANSMIT_STATUS(&CanHandle, CAN_TXMAILBOX_2); + if(tmp1 || tmp2 || tmp3) + { + irq_handler(can_irq_ids[id], IRQ_TX); + } + } + + tmp1 = __HAL_CAN_MSG_PENDING(&CanHandle, CAN_FIFO0); + tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_FMP0); + + if((tmp1 != 0) && tmp2) { + irq_handler(can_irq_ids[id], IRQ_RX); + } + + tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_EPV); + tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_EPV); + tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); + + if(tmp1 && tmp2 && tmp3) { + irq_handler(can_irq_ids[id], IRQ_PASSIVE); + } + + tmp1 = __HAL_CAN_GET_FLAG(&CanHandle, CAN_FLAG_BOF); + tmp2 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_BOF); + tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); + if(tmp1 && tmp2 && tmp3) { + irq_handler(can_irq_ids[id], IRQ_BUS); + } + + tmp3 = __HAL_CAN_GET_IT_SOURCE(&CanHandle, CAN_IT_ERR); + if(tmp1 && tmp2 && tmp3) { + irq_handler(can_irq_ids[id], IRQ_ERROR); + } +} + +void CAN_RX0_IRQHandler(void) +{ + can_irq(CAN_1, 0); +} + +void CAN_TX_IRQHandler(void) +{ + can_irq(CAN_1, 0); +} + +void CAN_SCE_IRQHandler(void) +{ + can_irq(CAN_1, 0); +} + +void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) +{ + + CAN_TypeDef *can = (CAN_TypeDef *)(obj->can); + IRQn_Type irq_n = (IRQn_Type)0; + uint32_t vector = 0; + uint32_t ier; + + if(obj->can == CAN_1) { + switch (type) { + case IRQ_RX: + ier = CAN_IT_FMP0; + irq_n = CAN_RX0_IRQn; + vector = (uint32_t)&CAN_RX0_IRQHandler; + break; + case IRQ_TX: + ier = CAN_IT_TME; + irq_n = CAN_TX_IRQn; + vector = (uint32_t)&CAN_TX_IRQHandler; + break; + case IRQ_ERROR: + ier = CAN_IT_ERR; + irq_n = CAN_SCE_IRQn; + vector = (uint32_t)&CAN_SCE_IRQHandler; + break; + case IRQ_PASSIVE: + ier = CAN_IT_EPV; + irq_n = CAN_SCE_IRQn; + vector = (uint32_t)&CAN_SCE_IRQHandler; + break; + case IRQ_BUS: + ier = CAN_IT_BOF; + irq_n = CAN_SCE_IRQn; + vector = (uint32_t)&CAN_SCE_IRQHandler; + break; + default: return; + } + } + + if(enable) { + can->IER |= ier; + } else { + can->IER &= ~ier; + } + + NVIC_SetVector(irq_n, vector); + NVIC_EnableIRQ(irq_n); +} + +#endif // DEVICE_CAN + From 656d1953d9e982c4000aba4ebf45f770c51da132 Mon Sep 17 00:00:00 2001 From: Bartosz Szczepanski Date: Tue, 19 Apr 2016 16:37:20 +0200 Subject: [PATCH 02/87] [NUCLEO_F334R8] Added CAN support Added CAN API support for NUCLEO_F334R8 target. *stm32f334x8.h* file was changed to avoid compilation errors. Change-Id: Ic7b3273ffe24940ecdc189d2566a6a7f66825ce6 --- .../TARGET_NUCLEO_F334R8/stm32f334x8.h | 2 +- .../TARGET_NUCLEO_F334R8/PeripheralNames.h | 4 ++++ .../TARGET_NUCLEO_F334R8/PeripheralPins.c | 12 ++++++++++++ .../TARGET_STM32F3/TARGET_NUCLEO_F334R8/device.h | 2 ++ .../TARGET_STM32F3/TARGET_NUCLEO_F334R8/objects.h | 5 +++++ libraries/tests/mbed/can/main.cpp | 4 ++-- libraries/tests/mbed/can_interrupt/main.cpp | 6 +++--- libraries/tests/mbed/can_loopback/main.cpp | 2 +- workspace_tools/tests.py | 7 ++++--- 9 files changed, 34 insertions(+), 10 deletions(-) diff --git a/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/stm32f334x8.h b/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/stm32f334x8.h index eb81cb9745f..8e2da1096fd 100644 --- a/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/stm32f334x8.h +++ b/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/stm32f334x8.h @@ -872,7 +872,7 @@ typedef struct #define USART2 ((USART_TypeDef *) USART2_BASE) #define USART3 ((USART_TypeDef *) USART3_BASE) #define I2C1 ((I2C_TypeDef *) I2C1_BASE) -#define CAN ((CAN_TypeDef *) CAN_BASE) +#define CAN1 ((CAN_TypeDef *) CAN_BASE) #define PWR ((PWR_TypeDef *) PWR_BASE) #define DAC1 ((DAC_TypeDef *) DAC1_BASE) #define DAC2 ((DAC_TypeDef *) DAC2_BASE) diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/PeripheralNames.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/PeripheralNames.h index 1b14ad27dea..efde3b38292 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/PeripheralNames.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/PeripheralNames.h @@ -73,6 +73,10 @@ typedef enum { PWM_17 = (int)TIM17_BASE } PWMName; +typedef enum { + CAN_1 = (int)CAN_BASE +} CANName; + #ifdef __cplusplus } #endif diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/PeripheralPins.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/PeripheralPins.c index 31ccce129d8..ec22f6efde6 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/PeripheralPins.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/PeripheralPins.c @@ -210,3 +210,15 @@ const PinMap PinMap_SPI_SSEL[] = { {PA_15, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, {NC, NC, 0} }; + +const PinMap PinMap_CAN_RD[] = { + {PB_8 , CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN)}, + {PA_11, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN)}, + {NC, NC, 0} +}; + +const PinMap PinMap_CAN_TD[] = { + {PB_9 , CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN)}, + {PA_12, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN)}, + {NC, NC, 0} +}; diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/device.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/device.h index 8b1f3d7ca23..63b22fe2165 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/device.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/device.h @@ -54,6 +54,8 @@ #define DEVICE_SLEEP 1 +#define DEVICE_CAN 1 + //======================================= #define DEVICE_SEMIHOST 0 diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/objects.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/objects.h index a1cba7d5836..81ebc1d3710 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/objects.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F334R8/objects.h @@ -106,6 +106,11 @@ struct pwmout_s { uint32_t inverted; }; +struct can_s { + CANName can; + int index; +}; + #include "gpio_object.h" #ifdef __cplusplus diff --git a/libraries/tests/mbed/can/main.cpp b/libraries/tests/mbed/can/main.cpp index 7302ae9ba9a..6a01cc9b686 100644 --- a/libraries/tests/mbed/can/main.cpp +++ b/libraries/tests/mbed/can/main.cpp @@ -15,7 +15,7 @@ CAN can1(D2, D3); // B96B_F446VE support only single CAN channel CAN can1(PD_0, PD_1); #elif defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F072RB) || \ - defined(TARGET_NUCLEO_F042K6) + defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) CAN can1(PA_11, PA_12); #else CAN can1(p9, p10); @@ -53,7 +53,7 @@ int main() { while(1) { #if (!defined (TARGET_LPC1549) && !defined(TARGET_B96B_F446VE) && \ !defined(TARGET_NUCLEO_F091RC) && !defined(TARGET_NUCLEO_F072RB) && \ - !defined(TARGET_NUCLEO_F042K6)) + !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8)) printf("loop()\n"); if(can2.read(msg)) { printmsg("Rx message:", &msg); diff --git a/libraries/tests/mbed/can_interrupt/main.cpp b/libraries/tests/mbed/can_interrupt/main.cpp index e9937a669b8..5d18bf40c89 100644 --- a/libraries/tests/mbed/can_interrupt/main.cpp +++ b/libraries/tests/mbed/can_interrupt/main.cpp @@ -15,7 +15,7 @@ CAN can1(D2, D3); // B96B_F446VE support only single CAN channel CAN can1(PD_0, PD_1); #elif defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F072RB) || \ - defined(TARGET_NUCLEO_F042K6) + defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) CAN can1(PA_11, PA_12); #else CAN can1(p9, p10); @@ -48,7 +48,7 @@ void send() { #if (!defined (TARGET_LPC1549) && !defined(TARGET_B96B_F446VE) && \ !defined(TARGET_NUCLEO_F091RC) && !defined(TARGET_NUCLEO_F072RB) && \ - !defined(TARGET_NUCLEO_F042K6)) + !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8)) void read() { CANMessage msg; printf("rx()\n"); @@ -64,7 +64,7 @@ int main() { ticker.attach(&send, 1); #if (!defined (TARGET_LPC1549) && !defined(TARGET_B96B_F446VE) && \ !defined(TARGET_NUCLEO_F091RC) && !defined(TARGET_NUCLEO_F072RB) && \ - !defined(TARGET_NUCLEO_F042K6)) + !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8)) can2.attach(&read); #endif while(1) { diff --git a/libraries/tests/mbed/can_loopback/main.cpp b/libraries/tests/mbed/can_loopback/main.cpp index 62006c4972a..d036352aac3 100644 --- a/libraries/tests/mbed/can_loopback/main.cpp +++ b/libraries/tests/mbed/can_loopback/main.cpp @@ -14,7 +14,7 @@ CAN can1(PD_0, PD_1); #elif defined(TARGET_VK_RZ_A1H) CAN can1(P5_9, P5_10); #elif defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F072RB) || \ - defined(TARGET_NUCLEO_F042K6) + defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) CAN can1(PA_11, PA_12); #endif diff --git a/workspace_tools/tests.py b/workspace_tools/tests.py index fe83367ea91..4f6a8b23958 100644 --- a/workspace_tools/tests.py +++ b/workspace_tools/tests.py @@ -94,6 +94,7 @@ * NUCLEO_F091RC: (RX=PA_11, TX=PA_12) * NUCLEO_F072RB: (RX=PA_11, TX=PA_12) * NUCLEO_F042K6: (RX=PA_11, TX=PA_12) + * NUCLEO_F334R8: (RX=PA_11, TX=PA_12) """ TESTS = [ @@ -300,7 +301,7 @@ "duration": 20, "peripherals": ["can_transceiver"], "mcu": ["LPC1549", "LPC1768","B96B_F446VE", "VK_RZ_A1H", - "NUCLEO_F091RC", "NUCLEO_F072RB", "NUCLEO_F042K6"], + "NUCLEO_F091RC", "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8"], }, { "id": "MBED_BLINKY", "description": "Blinky", @@ -572,14 +573,14 @@ "source_dir": join(TEST_DIR, "mbed", "can"), "dependencies": [MBED_LIBRARIES], "mcu": ["LPC1768", "LPC4088", "LPC1549", "RZ_A1H", "B96B_F446VE", "NUCLEO_F091RC", - "NUCLEO_F072RB", "NUCLEO_F042K6"] + "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8"] }, { "id": "MBED_30", "description": "CAN network test using interrupts", "source_dir": join(TEST_DIR, "mbed", "can_interrupt"), "dependencies": [MBED_LIBRARIES], "mcu": ["LPC1768", "LPC4088", "LPC1549", "RZ_A1H", "B96B_F446VE", "NUCLEO_F091RC", - "NUCLEO_F072RB", "NUCLEO_F042K6"] + "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8"] }, { "id": "MBED_31", "description": "PWM LED test", From 9a78b010a0fc51d42a87fa759972e1c27981c3f5 Mon Sep 17 00:00:00 2001 From: Bartosz Szczepanski Date: Tue, 19 Apr 2016 16:42:05 +0200 Subject: [PATCH 03/87] [NUCLEO_F303RE] Added CAN support Added CAN API support for NUCLEO_F303RE target. *stm32f303xe.h* file was changed to avoid compilation errors. Change-Id: Ia6519c982261d43165dbce73cab7cfc0617474e2 --- .../TARGET_NUCLEO_F303RE/stm32f303xe.h | 2 +- .../TARGET_NUCLEO_F303RE/PeripheralNames.h | 4 ++++ .../TARGET_NUCLEO_F303RE/PeripheralPins.c | 12 ++++++++++++ .../TARGET_STM32F3/TARGET_NUCLEO_F303RE/device.h | 2 ++ .../TARGET_STM32F3/TARGET_NUCLEO_F303RE/objects.h | 5 +++++ libraries/tests/mbed/can/main.cpp | 6 ++++-- libraries/tests/mbed/can_interrupt/main.cpp | 9 ++++++--- libraries/tests/mbed/can_loopback/main.cpp | 3 ++- workspace_tools/tests.py | 8 +++++--- 9 files changed, 41 insertions(+), 10 deletions(-) diff --git a/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/stm32f303xe.h b/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/stm32f303xe.h index 521e35014ec..31bd2fd1d73 100644 --- a/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/stm32f303xe.h +++ b/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/stm32f303xe.h @@ -924,7 +924,7 @@ typedef struct #define UART5 ((USART_TypeDef *) UART5_BASE) #define I2C1 ((I2C_TypeDef *) I2C1_BASE) #define I2C2 ((I2C_TypeDef *) I2C2_BASE) -#define CAN ((CAN_TypeDef *) CAN_BASE) +#define CAN1 ((CAN_TypeDef *) CAN_BASE) #define PWR ((PWR_TypeDef *) PWR_BASE) #define DAC ((DAC_TypeDef *) DAC_BASE) #define DAC1 ((DAC_TypeDef *) DAC1_BASE) diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/PeripheralNames.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/PeripheralNames.h index 903555601c6..1b2dd8f02d3 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/PeripheralNames.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/PeripheralNames.h @@ -82,6 +82,10 @@ typedef enum { PWM_17 = (int)TIM17_BASE } PWMName; +typedef enum { + CAN_1 = (int)CAN_BASE +} CANName; + #ifdef __cplusplus } #endif diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/PeripheralPins.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/PeripheralPins.c index 813a9a9553d..13c33f170f0 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/PeripheralPins.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/PeripheralPins.c @@ -255,3 +255,15 @@ const PinMap PinMap_SPI_SSEL[] = { {PF_0, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, {NC, NC, 0} }; + +const PinMap PinMap_CAN_RD[] = { + {PB_8 , CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN)}, + {PA_11, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN)}, + {NC, NC, 0} +}; + +const PinMap PinMap_CAN_TD[] = { + {PB_9 , CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN)}, + {PA_12, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN)}, + {NC, NC, 0} +}; diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/device.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/device.h index 8b1f3d7ca23..63b22fe2165 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/device.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/device.h @@ -54,6 +54,8 @@ #define DEVICE_SLEEP 1 +#define DEVICE_CAN 1 + //======================================= #define DEVICE_SEMIHOST 0 diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/objects.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/objects.h index a1cba7d5836..81ebc1d3710 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/objects.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303RE/objects.h @@ -106,6 +106,11 @@ struct pwmout_s { uint32_t inverted; }; +struct can_s { + CANName can; + int index; +}; + #include "gpio_object.h" #ifdef __cplusplus diff --git a/libraries/tests/mbed/can/main.cpp b/libraries/tests/mbed/can/main.cpp index 6a01cc9b686..7366f9fafc7 100644 --- a/libraries/tests/mbed/can/main.cpp +++ b/libraries/tests/mbed/can/main.cpp @@ -15,7 +15,8 @@ CAN can1(D2, D3); // B96B_F446VE support only single CAN channel CAN can1(PD_0, PD_1); #elif defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F072RB) || \ - defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) + defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) || \ + defined(TARGET_NUCLEO_F303RE) CAN can1(PA_11, PA_12); #else CAN can1(p9, p10); @@ -53,7 +54,8 @@ int main() { while(1) { #if (!defined (TARGET_LPC1549) && !defined(TARGET_B96B_F446VE) && \ !defined(TARGET_NUCLEO_F091RC) && !defined(TARGET_NUCLEO_F072RB) && \ - !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8)) + !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8) && \ + !defined(TARGET_NUCLEO_F303RE)) printf("loop()\n"); if(can2.read(msg)) { printmsg("Rx message:", &msg); diff --git a/libraries/tests/mbed/can_interrupt/main.cpp b/libraries/tests/mbed/can_interrupt/main.cpp index 5d18bf40c89..8a9679bcb3f 100644 --- a/libraries/tests/mbed/can_interrupt/main.cpp +++ b/libraries/tests/mbed/can_interrupt/main.cpp @@ -15,7 +15,8 @@ CAN can1(D2, D3); // B96B_F446VE support only single CAN channel CAN can1(PD_0, PD_1); #elif defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F072RB) || \ - defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) + defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) || \ + defined(TARGET_NUCLEO_F303RE) CAN can1(PA_11, PA_12); #else CAN can1(p9, p10); @@ -48,7 +49,8 @@ void send() { #if (!defined (TARGET_LPC1549) && !defined(TARGET_B96B_F446VE) && \ !defined(TARGET_NUCLEO_F091RC) && !defined(TARGET_NUCLEO_F072RB) && \ - !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8)) + !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8) && \ + !defined(TARGET_NUCLEO_F303RE)) void read() { CANMessage msg; printf("rx()\n"); @@ -64,7 +66,8 @@ int main() { ticker.attach(&send, 1); #if (!defined (TARGET_LPC1549) && !defined(TARGET_B96B_F446VE) && \ !defined(TARGET_NUCLEO_F091RC) && !defined(TARGET_NUCLEO_F072RB) && \ - !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8)) + !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8) && \ + !defined(TARGET_NUCLEO_F303RE)) can2.attach(&read); #endif while(1) { diff --git a/libraries/tests/mbed/can_loopback/main.cpp b/libraries/tests/mbed/can_loopback/main.cpp index d036352aac3..6c3917d1e56 100644 --- a/libraries/tests/mbed/can_loopback/main.cpp +++ b/libraries/tests/mbed/can_loopback/main.cpp @@ -14,7 +14,8 @@ CAN can1(PD_0, PD_1); #elif defined(TARGET_VK_RZ_A1H) CAN can1(P5_9, P5_10); #elif defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F072RB) || \ - defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) + defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) || \ + defined(TARGET_NUCLEO_F303RE) CAN can1(PA_11, PA_12); #endif diff --git a/workspace_tools/tests.py b/workspace_tools/tests.py index 4f6a8b23958..656a059ce9a 100644 --- a/workspace_tools/tests.py +++ b/workspace_tools/tests.py @@ -95,6 +95,7 @@ * NUCLEO_F072RB: (RX=PA_11, TX=PA_12) * NUCLEO_F042K6: (RX=PA_11, TX=PA_12) * NUCLEO_F334R8: (RX=PA_11, TX=PA_12) + * NUCLEO_F303RE: (RX=PA_11, TX=PA_12) """ TESTS = [ @@ -301,7 +302,8 @@ "duration": 20, "peripherals": ["can_transceiver"], "mcu": ["LPC1549", "LPC1768","B96B_F446VE", "VK_RZ_A1H", - "NUCLEO_F091RC", "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8"], + "NUCLEO_F091RC", "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8", + "NUCLEO_F303RE"], }, { "id": "MBED_BLINKY", "description": "Blinky", @@ -573,14 +575,14 @@ "source_dir": join(TEST_DIR, "mbed", "can"), "dependencies": [MBED_LIBRARIES], "mcu": ["LPC1768", "LPC4088", "LPC1549", "RZ_A1H", "B96B_F446VE", "NUCLEO_F091RC", - "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8"] + "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8", "NUCLEO_F303RE"] }, { "id": "MBED_30", "description": "CAN network test using interrupts", "source_dir": join(TEST_DIR, "mbed", "can_interrupt"), "dependencies": [MBED_LIBRARIES], "mcu": ["LPC1768", "LPC4088", "LPC1549", "RZ_A1H", "B96B_F446VE", "NUCLEO_F091RC", - "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8"] + "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8", "NUCLEO_F303RE"] }, { "id": "MBED_31", "description": "PWM LED test", From 347a5e629d5aad20bbff60f5af4a8f8e7186a427 Mon Sep 17 00:00:00 2001 From: Bartosz Szczepanski Date: Tue, 19 Apr 2016 16:05:22 +0200 Subject: [PATCH 04/87] [NUCLEO_F303K8] Added CAN support Added CAN API support for NUCLEO_F303K8 target. *stm32f303x8.h* file was changed to avoid compilation errors. Change-Id: If093c84f19c5a5ef68938af4653a25271c1108ba --- .../TARGET_STM32F3/TARGET_NUCLEO_F303K8/stm32f303x8.h | 2 +- .../TARGET_NUCLEO_F303K8/PeripheralNames.h | 4 ++++ .../TARGET_NUCLEO_F303K8/PeripheralPins.c | 10 ++++++++++ .../TARGET_STM32F3/TARGET_NUCLEO_F303K8/device.h | 2 ++ .../TARGET_STM32F3/TARGET_NUCLEO_F303K8/objects.h | 5 +++++ libraries/tests/mbed/can/main.cpp | 4 ++-- libraries/tests/mbed/can_interrupt/main.cpp | 6 +++--- libraries/tests/mbed/can_loopback/main.cpp | 2 +- workspace_tools/tests.py | 9 ++++++--- 9 files changed, 34 insertions(+), 10 deletions(-) diff --git a/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/stm32f303x8.h b/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/stm32f303x8.h index 4a41089bd21..d576678cea7 100644 --- a/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/stm32f303x8.h +++ b/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/stm32f303x8.h @@ -758,7 +758,7 @@ typedef struct #define USART2 ((USART_TypeDef *) USART2_BASE) #define USART3 ((USART_TypeDef *) USART3_BASE) #define I2C1 ((I2C_TypeDef *) I2C1_BASE) -#define CAN ((CAN_TypeDef *) CAN_BASE) +#define CAN1 ((CAN_TypeDef *) CAN_BASE) #define PWR ((PWR_TypeDef *) PWR_BASE) #define DAC1 ((DAC_TypeDef *) DAC1_BASE) #define DAC2 ((DAC_TypeDef *) DAC2_BASE) diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/PeripheralNames.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/PeripheralNames.h index 8dabf2d47b8..8b039529e59 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/PeripheralNames.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/PeripheralNames.h @@ -72,6 +72,10 @@ typedef enum { PWM_17 = (int)TIM17_BASE } PWMName; +typedef enum { + CAN_1 = (int)CAN_BASE +} CANName; + #ifdef __cplusplus } #endif diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/PeripheralPins.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/PeripheralPins.c index 5ef3a7eb2ab..6dbd71c70a3 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/PeripheralPins.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/PeripheralPins.c @@ -169,3 +169,13 @@ const PinMap PinMap_SPI_SSEL[] = { {PA_15, SPI_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI1)}, {NC, NC, 0} }; + +const PinMap PinMap_CAN_RD[] = { + {PA_11, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN)}, + {NC, NC, 0} +}; + +const PinMap PinMap_CAN_TD[] = { + {PA_12, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN)}, + {NC, NC, 0} +}; diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/device.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/device.h index 8b1f3d7ca23..63b22fe2165 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/device.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/device.h @@ -54,6 +54,8 @@ #define DEVICE_SLEEP 1 +#define DEVICE_CAN 1 + //======================================= #define DEVICE_SEMIHOST 0 diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/objects.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/objects.h index a1cba7d5836..81ebc1d3710 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/objects.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F303K8/objects.h @@ -106,6 +106,11 @@ struct pwmout_s { uint32_t inverted; }; +struct can_s { + CANName can; + int index; +}; + #include "gpio_object.h" #ifdef __cplusplus diff --git a/libraries/tests/mbed/can/main.cpp b/libraries/tests/mbed/can/main.cpp index 7366f9fafc7..47859bb1819 100644 --- a/libraries/tests/mbed/can/main.cpp +++ b/libraries/tests/mbed/can/main.cpp @@ -16,7 +16,7 @@ CAN can1(D2, D3); CAN can1(PD_0, PD_1); #elif defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F072RB) || \ defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) || \ - defined(TARGET_NUCLEO_F303RE) + defined(TARGET_NUCLEO_F303RE) || defined(TARGET_NUCLEO_F303K8) CAN can1(PA_11, PA_12); #else CAN can1(p9, p10); @@ -55,7 +55,7 @@ int main() { #if (!defined (TARGET_LPC1549) && !defined(TARGET_B96B_F446VE) && \ !defined(TARGET_NUCLEO_F091RC) && !defined(TARGET_NUCLEO_F072RB) && \ !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8) && \ - !defined(TARGET_NUCLEO_F303RE)) + !defined(TARGET_NUCLEO_F303RE) && !defined(TARGET_NUCLEO_F303K8)) printf("loop()\n"); if(can2.read(msg)) { printmsg("Rx message:", &msg); diff --git a/libraries/tests/mbed/can_interrupt/main.cpp b/libraries/tests/mbed/can_interrupt/main.cpp index 8a9679bcb3f..d34afc910af 100644 --- a/libraries/tests/mbed/can_interrupt/main.cpp +++ b/libraries/tests/mbed/can_interrupt/main.cpp @@ -16,7 +16,7 @@ CAN can1(D2, D3); CAN can1(PD_0, PD_1); #elif defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F072RB) || \ defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) || \ - defined(TARGET_NUCLEO_F303RE) + defined(TARGET_NUCLEO_F303RE) || defined(TARGET_NUCLEO_F303K8) CAN can1(PA_11, PA_12); #else CAN can1(p9, p10); @@ -50,7 +50,7 @@ void send() { #if (!defined (TARGET_LPC1549) && !defined(TARGET_B96B_F446VE) && \ !defined(TARGET_NUCLEO_F091RC) && !defined(TARGET_NUCLEO_F072RB) && \ !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8) && \ - !defined(TARGET_NUCLEO_F303RE)) + !defined(TARGET_NUCLEO_F303RE) && !defined(TARGET_NUCLEO_F303K8)) void read() { CANMessage msg; printf("rx()\n"); @@ -67,7 +67,7 @@ int main() { #if (!defined (TARGET_LPC1549) && !defined(TARGET_B96B_F446VE) && \ !defined(TARGET_NUCLEO_F091RC) && !defined(TARGET_NUCLEO_F072RB) && \ !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8) && \ - !defined(TARGET_NUCLEO_F303RE)) + !defined(TARGET_NUCLEO_F303RE) && !defined(TARGET_NUCLEO_F303K8)) can2.attach(&read); #endif while(1) { diff --git a/libraries/tests/mbed/can_loopback/main.cpp b/libraries/tests/mbed/can_loopback/main.cpp index 6c3917d1e56..ccce8d2e9e5 100644 --- a/libraries/tests/mbed/can_loopback/main.cpp +++ b/libraries/tests/mbed/can_loopback/main.cpp @@ -15,7 +15,7 @@ CAN can1(PD_0, PD_1); CAN can1(P5_9, P5_10); #elif defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F072RB) || \ defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) || \ - defined(TARGET_NUCLEO_F303RE) + defined(TARGET_NUCLEO_F303RE) || defined(TARGET_NUCLEO_F303K8) CAN can1(PA_11, PA_12); #endif diff --git a/workspace_tools/tests.py b/workspace_tools/tests.py index 656a059ce9a..fb37cf38d5f 100644 --- a/workspace_tools/tests.py +++ b/workspace_tools/tests.py @@ -96,6 +96,7 @@ * NUCLEO_F042K6: (RX=PA_11, TX=PA_12) * NUCLEO_F334R8: (RX=PA_11, TX=PA_12) * NUCLEO_F303RE: (RX=PA_11, TX=PA_12) + * NUCLEO_F303K8: (RX=PA_11, TX=PA_12) """ TESTS = [ @@ -303,7 +304,7 @@ "peripherals": ["can_transceiver"], "mcu": ["LPC1549", "LPC1768","B96B_F446VE", "VK_RZ_A1H", "NUCLEO_F091RC", "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8", - "NUCLEO_F303RE"], + "NUCLEO_F303RE", "NUCLEO_F303K8"], }, { "id": "MBED_BLINKY", "description": "Blinky", @@ -575,14 +576,16 @@ "source_dir": join(TEST_DIR, "mbed", "can"), "dependencies": [MBED_LIBRARIES], "mcu": ["LPC1768", "LPC4088", "LPC1549", "RZ_A1H", "B96B_F446VE", "NUCLEO_F091RC", - "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8", "NUCLEO_F303RE"] + "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8", "NUCLEO_F303RE", + "NUCLEO_F303K8"] }, { "id": "MBED_30", "description": "CAN network test using interrupts", "source_dir": join(TEST_DIR, "mbed", "can_interrupt"), "dependencies": [MBED_LIBRARIES], "mcu": ["LPC1768", "LPC4088", "LPC1549", "RZ_A1H", "B96B_F446VE", "NUCLEO_F091RC", - "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8", "NUCLEO_F303RE"] + "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8", "NUCLEO_F303RE", + "NUCLEO_F303K8"] }, { "id": "MBED_31", "description": "PWM LED test", From f1c42bfc6914bb3a14532279e611a3316ff0a4bc Mon Sep 17 00:00:00 2001 From: Bartosz Szczepanski Date: Tue, 19 Apr 2016 16:16:12 +0200 Subject: [PATCH 05/87] [NUCLEO_F302R8] Added CAN support Added CAN API support for NUCLEO_F302R8 target. *stm32f302x8.h* file was changed to avoid compilation errors. Change-Id: Ia4ee8a90fe3f0ad6955dde21e78ea4a6c05e4fcd --- .../TARGET_NUCLEO_F302R8/stm32f302x8.h | 2 +- .../TARGET_NUCLEO_F302R8/PeripheralNames.h | 4 ++++ .../TARGET_NUCLEO_F302R8/PeripheralPins.c | 12 ++++++++++++ .../TARGET_STM32F3/TARGET_NUCLEO_F302R8/device.h | 2 ++ .../TARGET_STM32F3/TARGET_NUCLEO_F302R8/objects.h | 5 +++++ libraries/tests/mbed/can/main.cpp | 6 ++++-- libraries/tests/mbed/can_interrupt/main.cpp | 9 ++++++--- libraries/tests/mbed/can_loopback/main.cpp | 3 ++- workspace_tools/tests.py | 7 ++++--- 9 files changed, 40 insertions(+), 10 deletions(-) diff --git a/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/stm32f302x8.h b/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/stm32f302x8.h index 0bd53c4f0b2..dd8c09cda32 100644 --- a/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/stm32f302x8.h +++ b/hal/targets/cmsis/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/stm32f302x8.h @@ -792,7 +792,7 @@ typedef struct #define I2C1 ((I2C_TypeDef *) I2C1_BASE) #define I2C2 ((I2C_TypeDef *) I2C2_BASE) #define I2C3 ((I2C_TypeDef *) I2C3_BASE) -#define CAN ((CAN_TypeDef *) CAN_BASE) +#define CAN1 ((CAN_TypeDef *) CAN_BASE) #define PWR ((PWR_TypeDef *) PWR_BASE) #define DAC ((DAC_TypeDef *) DAC_BASE) #define DAC1 ((DAC_TypeDef *) DAC1_BASE) diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/PeripheralNames.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/PeripheralNames.h index 720cb97e8a3..4c9aa7c4a17 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/PeripheralNames.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/PeripheralNames.h @@ -73,6 +73,10 @@ typedef enum { PWM_17 = (int)TIM17_BASE } PWMName; +typedef enum { + CAN_1 = (int)CAN_BASE +} CANName; + #ifdef __cplusplus } #endif diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/PeripheralPins.c b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/PeripheralPins.c index 3ef1afb5259..a8695d8a749 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/PeripheralPins.c +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/PeripheralPins.c @@ -204,3 +204,15 @@ const PinMap PinMap_SPI_SSEL[] = { {PF_0, SPI_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF5_SPI2)}, {NC, NC, 0} }; + +const PinMap PinMap_CAN_RD[] = { +// {PB_8 , CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN)}, // Not available in 32 pins package + {PA_11, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN)}, + {NC, NC, 0} +}; + +const PinMap PinMap_CAN_TD[] = { +// {PB_9 , CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN)}, // Not available in 32 pins package + {PA_12, CAN_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF9_CAN)}, + {NC, NC, 0} +}; diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/device.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/device.h index 8b1f3d7ca23..63b22fe2165 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/device.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/device.h @@ -54,6 +54,8 @@ #define DEVICE_SLEEP 1 +#define DEVICE_CAN 1 + //======================================= #define DEVICE_SEMIHOST 0 diff --git a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/objects.h b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/objects.h index a1cba7d5836..81ebc1d3710 100644 --- a/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/objects.h +++ b/hal/targets/hal/TARGET_STM/TARGET_STM32F3/TARGET_NUCLEO_F302R8/objects.h @@ -106,6 +106,11 @@ struct pwmout_s { uint32_t inverted; }; +struct can_s { + CANName can; + int index; +}; + #include "gpio_object.h" #ifdef __cplusplus diff --git a/libraries/tests/mbed/can/main.cpp b/libraries/tests/mbed/can/main.cpp index 47859bb1819..9c7f2dc333e 100644 --- a/libraries/tests/mbed/can/main.cpp +++ b/libraries/tests/mbed/can/main.cpp @@ -16,7 +16,8 @@ CAN can1(D2, D3); CAN can1(PD_0, PD_1); #elif defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F072RB) || \ defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) || \ - defined(TARGET_NUCLEO_F303RE) || defined(TARGET_NUCLEO_F303K8) + defined(TARGET_NUCLEO_F303RE) || defined(TARGET_NUCLEO_F303K8) || \ + defined(TARGET_NUCLEO_F302R8) CAN can1(PA_11, PA_12); #else CAN can1(p9, p10); @@ -55,7 +56,8 @@ int main() { #if (!defined (TARGET_LPC1549) && !defined(TARGET_B96B_F446VE) && \ !defined(TARGET_NUCLEO_F091RC) && !defined(TARGET_NUCLEO_F072RB) && \ !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8) && \ - !defined(TARGET_NUCLEO_F303RE) && !defined(TARGET_NUCLEO_F303K8)) + !defined(TARGET_NUCLEO_F303RE) && !defined(TARGET_NUCLEO_F303K8) && \ + !defined(TARGET_NUCLEO_F302R8)) printf("loop()\n"); if(can2.read(msg)) { printmsg("Rx message:", &msg); diff --git a/libraries/tests/mbed/can_interrupt/main.cpp b/libraries/tests/mbed/can_interrupt/main.cpp index d34afc910af..08a8e1919fe 100644 --- a/libraries/tests/mbed/can_interrupt/main.cpp +++ b/libraries/tests/mbed/can_interrupt/main.cpp @@ -16,7 +16,8 @@ CAN can1(D2, D3); CAN can1(PD_0, PD_1); #elif defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F072RB) || \ defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) || \ - defined(TARGET_NUCLEO_F303RE) || defined(TARGET_NUCLEO_F303K8) + defined(TARGET_NUCLEO_F303RE) || defined(TARGET_NUCLEO_F303K8) || \ + defined(TARGET_NUCLEO_F302R8) CAN can1(PA_11, PA_12); #else CAN can1(p9, p10); @@ -50,7 +51,8 @@ void send() { #if (!defined (TARGET_LPC1549) && !defined(TARGET_B96B_F446VE) && \ !defined(TARGET_NUCLEO_F091RC) && !defined(TARGET_NUCLEO_F072RB) && \ !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8) && \ - !defined(TARGET_NUCLEO_F303RE) && !defined(TARGET_NUCLEO_F303K8)) + !defined(TARGET_NUCLEO_F303RE) && !defined(TARGET_NUCLEO_F303K8) && \ + !defined(TARGET_NUCLEO_F302R8)) void read() { CANMessage msg; printf("rx()\n"); @@ -67,7 +69,8 @@ int main() { #if (!defined (TARGET_LPC1549) && !defined(TARGET_B96B_F446VE) && \ !defined(TARGET_NUCLEO_F091RC) && !defined(TARGET_NUCLEO_F072RB) && \ !defined(TARGET_NUCLEO_F042K6) && !defined(TARGET_NUCLEO_F334R8) && \ - !defined(TARGET_NUCLEO_F303RE) && !defined(TARGET_NUCLEO_F303K8)) + !defined(TARGET_NUCLEO_F303RE) && !defined(TARGET_NUCLEO_F303K8) && \ + !defined(TARGET_NUCLEO_F302R8)) can2.attach(&read); #endif while(1) { diff --git a/libraries/tests/mbed/can_loopback/main.cpp b/libraries/tests/mbed/can_loopback/main.cpp index ccce8d2e9e5..d325ff76362 100644 --- a/libraries/tests/mbed/can_loopback/main.cpp +++ b/libraries/tests/mbed/can_loopback/main.cpp @@ -15,7 +15,8 @@ CAN can1(PD_0, PD_1); CAN can1(P5_9, P5_10); #elif defined(TARGET_NUCLEO_F091RC) || defined(TARGET_NUCLEO_F072RB) || \ defined(TARGET_NUCLEO_F042K6) || defined(TARGET_NUCLEO_F334R8) || \ - defined(TARGET_NUCLEO_F303RE) || defined(TARGET_NUCLEO_F303K8) + defined(TARGET_NUCLEO_F303RE) || defined(TARGET_NUCLEO_F303K8) || \ + defined(TARGET_NUCLEO_F302R8) CAN can1(PA_11, PA_12); #endif diff --git a/workspace_tools/tests.py b/workspace_tools/tests.py index fb37cf38d5f..6dda3900152 100644 --- a/workspace_tools/tests.py +++ b/workspace_tools/tests.py @@ -97,6 +97,7 @@ * NUCLEO_F334R8: (RX=PA_11, TX=PA_12) * NUCLEO_F303RE: (RX=PA_11, TX=PA_12) * NUCLEO_F303K8: (RX=PA_11, TX=PA_12) + * NUCLEO_F302R8: (RX=PA_11, TX=PA_12) """ TESTS = [ @@ -304,7 +305,7 @@ "peripherals": ["can_transceiver"], "mcu": ["LPC1549", "LPC1768","B96B_F446VE", "VK_RZ_A1H", "NUCLEO_F091RC", "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8", - "NUCLEO_F303RE", "NUCLEO_F303K8"], + "NUCLEO_F303RE", "NUCLEO_F303K8", "NUCLEO_F302R8"], }, { "id": "MBED_BLINKY", "description": "Blinky", @@ -577,7 +578,7 @@ "dependencies": [MBED_LIBRARIES], "mcu": ["LPC1768", "LPC4088", "LPC1549", "RZ_A1H", "B96B_F446VE", "NUCLEO_F091RC", "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8", "NUCLEO_F303RE", - "NUCLEO_F303K8"] + "NUCLEO_F303K8", "NUCLEO_F302R8"] }, { "id": "MBED_30", "description": "CAN network test using interrupts", @@ -585,7 +586,7 @@ "dependencies": [MBED_LIBRARIES], "mcu": ["LPC1768", "LPC4088", "LPC1549", "RZ_A1H", "B96B_F446VE", "NUCLEO_F091RC", "NUCLEO_F072RB", "NUCLEO_F042K6", "NUCLEO_F334R8", "NUCLEO_F303RE", - "NUCLEO_F303K8"] + "NUCLEO_F303K8", "NUCLEO_F302R8"] }, { "id": "MBED_31", "description": "PWM LED test", From 61e229603765a9103b905ca2ce57ec7eac96a7d9 Mon Sep 17 00:00:00 2001 From: Adam Green Date: Wed, 25 May 2016 00:20:06 -0700 Subject: [PATCH 06/87] Fix NXP LPCxxxx i2c_start() handling of repeated start In repeating start scenarios, there was a bug in the I2C driver for various NXP LPCxxxx parts which could allow an extra I/O from the previous operation to leak through. The scenario I encountered which triggered this bug went like so: * The higher level application code would first do an I2C write that doesn't send a stop bit (use repeating start instead.) * The higher level application code would then issues an I2C read operation which begin with a call to i2c_start(). * i2c_start() would clear the SI bit (interrupt flag) at the top of its implementation. * i2C_start() would then get interrupted right after clearing the SI bit. * While the CPU is off running the ISR code, the I2C peripheral repeats the last byte written to I2CDAT and then sets the SI bit to indicate that the write has completed. * The ISR returns to allow the i2c_start() to continue execution. * i2c_start() would then set the STA bit but it is too late. * i2c_start() waits for the SI bit to be set but it is already set because of the completed byte write and not because of the repeated start as expected. For me this bug would cause strange interactions between my ISRs and the code using I2C to read from the MPU-6050 IMU. I would be getting valid orientation data and then all of a sudden I would start receiving what looked like random values but I think it was just reading from the incorrect offset in the device's FIFO. It appears that atleast one other person has seen this before but it was never root caused since it required specific timing to reproduce: https://developer.mbed.org/forum/bugs-suggestions/topic/4254/ This bug can be found in most of the NXP I2C drivers and this commit contains a fix for them all. I however only have the LPC1768 and LPC11U24 for testing. My fix does the following: * No longer clears the SI bit in the i2c_conclr() call near the beginning of the i2c_start() function. It was this clear that previously caused the problem as described above. * The second part of the fix was to instead clear the SI bit after the STA (start) bit has been set with the i2c_conset() call. * The clearing of the SI bit should be skipped if there isn't an active interrupt when first entering i2c_start(). If you clear the SI bit when there isn't an active interrupt then the code is likely to skip over the interrupt for the start bit which was just sent and then allow the I2C peripheral to start sending the slave address before it has even been loaded into the I2CDAT register. --- .../hal/TARGET_NXP/TARGET_LPC11U6X/i2c_api.c | 18 ++++++++++++------ .../hal/TARGET_NXP/TARGET_LPC11UXX/i2c_api.c | 18 ++++++++++++------ .../TARGET_NXP/TARGET_LPC11XX_11CXX/i2c_api.c | 18 ++++++++++++------ .../hal/TARGET_NXP/TARGET_LPC13XX/i2c_api.c | 18 ++++++++++++------ .../hal/TARGET_NXP/TARGET_LPC176X/i2c_api.c | 18 ++++++++++++------ .../hal/TARGET_NXP/TARGET_LPC23XX/i2c_api.c | 18 ++++++++++++------ .../hal/TARGET_NXP/TARGET_LPC2460/i2c_api.c | 18 ++++++++++++------ .../TARGET_LPC408X/TARGET_LPC4088/i2c_api.c | 18 ++++++++++++------ .../TARGET_LPC408X/TARGET_LPC4088_DM/i2c_api.c | 12 +++++++++--- .../hal/TARGET_NXP/TARGET_LPC43XX/i2c_api.c | 18 ++++++++++++------ 10 files changed, 117 insertions(+), 57 deletions(-) diff --git a/hal/targets/hal/TARGET_NXP/TARGET_LPC11U6X/i2c_api.c b/hal/targets/hal/TARGET_NXP/TARGET_LPC11U6X/i2c_api.c index 718ef5ea0f2..84eeed8f93d 100644 --- a/hal/targets/hal/TARGET_NXP/TARGET_LPC11U6X/i2c_api.c +++ b/hal/targets/hal/TARGET_NXP/TARGET_LPC11U6X/i2c_api.c @@ -111,20 +111,26 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { inline int i2c_start(i2c_t *obj) { int status = 0; + int isInterrupted = I2C_CONSET(obj) & (1 << 3); + // 8.1 Before master mode can be entered, I2CON must be initialised to: // - I2EN STA STO SI AA - - - // - 1 0 0 0 x - - + // - 1 0 0 x x - - // if AA = 0, it can't enter slave mode - i2c_conclr(obj, 1, 1, 1, 1); - + i2c_conclr(obj, 1, 1, 0, 1); + // The master mode may now be entered by setting the STA bit // this will generate a start condition when the bus becomes free i2c_conset(obj, 1, 0, 0, 1); - + // Clearing SI bit when it wasn't set on entry can jump past state + // 0x10 or 0x08 and erroneously send uninitialized slave address. + if (isInterrupted) + i2c_clear_SI(obj); + i2c_wait_SI(obj); status = i2c_status(obj); - - // Clear start bit now transmitted, and interrupt bit + + // Clear start bit now that it's transmitted i2c_conclr(obj, 1, 0, 0, 0); return status; } diff --git a/hal/targets/hal/TARGET_NXP/TARGET_LPC11UXX/i2c_api.c b/hal/targets/hal/TARGET_NXP/TARGET_LPC11UXX/i2c_api.c index b100dc439ad..4c5202d6bc4 100644 --- a/hal/targets/hal/TARGET_NXP/TARGET_LPC11UXX/i2c_api.c +++ b/hal/targets/hal/TARGET_NXP/TARGET_LPC11UXX/i2c_api.c @@ -94,20 +94,26 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { inline int i2c_start(i2c_t *obj) { int status = 0; + int isInterrupted = I2C_CONSET(obj) & (1 << 3); + // 8.1 Before master mode can be entered, I2CON must be initialised to: // - I2EN STA STO SI AA - - - // - 1 0 0 0 x - - + // - 1 0 0 x x - - // if AA = 0, it can't enter slave mode - i2c_conclr(obj, 1, 1, 1, 1); - + i2c_conclr(obj, 1, 1, 0, 1); + // The master mode may now be entered by setting the STA bit // this will generate a start condition when the bus becomes free i2c_conset(obj, 1, 0, 0, 1); - + // Clearing SI bit when it wasn't set on entry can jump past state + // 0x10 or 0x08 and erroneously send uninitialized slave address. + if (isInterrupted) + i2c_clear_SI(obj); + i2c_wait_SI(obj); status = i2c_status(obj); - - // Clear start bit now transmitted, and interrupt bit + + // Clear start bit now that it's transmitted i2c_conclr(obj, 1, 0, 0, 0); return status; } diff --git a/hal/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/i2c_api.c b/hal/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/i2c_api.c index f4a271e1d09..52f6f4486e4 100644 --- a/hal/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/i2c_api.c +++ b/hal/targets/hal/TARGET_NXP/TARGET_LPC11XX_11CXX/i2c_api.c @@ -104,20 +104,26 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { inline int i2c_start(i2c_t *obj) { int status = 0; + int isInterrupted = I2C_CONSET(obj) & (1 << 3); + // 8.1 Before master mode can be entered, I2CON must be initialised to: // - I2EN STA STO SI AA - - - // - 1 0 0 0 x - - + // - 1 0 0 x x - - // if AA = 0, it can't enter slave mode - i2c_conclr(obj, 1, 1, 1, 1); - + i2c_conclr(obj, 1, 1, 0, 1); + // The master mode may now be entered by setting the STA bit // this will generate a start condition when the bus becomes free i2c_conset(obj, 1, 0, 0, 1); - + // Clearing SI bit when it wasn't set on entry can jump past state + // 0x10 or 0x08 and erroneously send uninitialized slave address. + if (isInterrupted) + i2c_clear_SI(obj); + i2c_wait_SI(obj); status = i2c_status(obj); - - // Clear start bit now transmitted, and interrupt bit + + // Clear start bit now that it's transmitted i2c_conclr(obj, 1, 0, 0, 0); return status; } diff --git a/hal/targets/hal/TARGET_NXP/TARGET_LPC13XX/i2c_api.c b/hal/targets/hal/TARGET_NXP/TARGET_LPC13XX/i2c_api.c index a19a87deb56..415ef071afb 100644 --- a/hal/targets/hal/TARGET_NXP/TARGET_LPC13XX/i2c_api.c +++ b/hal/targets/hal/TARGET_NXP/TARGET_LPC13XX/i2c_api.c @@ -104,20 +104,26 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { inline int i2c_start(i2c_t *obj) { int status = 0; + int isInterrupted = I2C_CONSET(obj) & (1 << 3); + // 8.1 Before master mode can be entered, I2CON must be initialised to: // - I2EN STA STO SI AA - - - // - 1 0 0 0 x - - + // - 1 0 0 x x - - // if AA = 0, it can't enter slave mode - i2c_conclr(obj, 1, 1, 1, 1); - + i2c_conclr(obj, 1, 1, 0, 1); + // The master mode may now be entered by setting the STA bit // this will generate a start condition when the bus becomes free i2c_conset(obj, 1, 0, 0, 1); - + // Clearing SI bit when it wasn't set on entry can jump past state + // 0x10 or 0x08 and erroneously send uninitialized slave address. + if (isInterrupted) + i2c_clear_SI(obj); + i2c_wait_SI(obj); status = i2c_status(obj); - - // Clear start bit now transmitted, and interrupt bit + + // Clear start bit now that it's transmitted i2c_conclr(obj, 1, 0, 0, 0); return status; } diff --git a/hal/targets/hal/TARGET_NXP/TARGET_LPC176X/i2c_api.c b/hal/targets/hal/TARGET_NXP/TARGET_LPC176X/i2c_api.c index ced04c3ca41..fb2ed1656a3 100644 --- a/hal/targets/hal/TARGET_NXP/TARGET_LPC176X/i2c_api.c +++ b/hal/targets/hal/TARGET_NXP/TARGET_LPC176X/i2c_api.c @@ -112,20 +112,26 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { inline int i2c_start(i2c_t *obj) { int status = 0; + int isInterrupted = I2C_CONSET(obj) & (1 << 3); + // 8.1 Before master mode can be entered, I2CON must be initialised to: // - I2EN STA STO SI AA - - - // - 1 0 0 0 x - - + // - 1 0 0 x x - - // if AA = 0, it can't enter slave mode - i2c_conclr(obj, 1, 1, 1, 1); - + i2c_conclr(obj, 1, 1, 0, 1); + // The master mode may now be entered by setting the STA bit // this will generate a start condition when the bus becomes free i2c_conset(obj, 1, 0, 0, 1); - + // Clearing SI bit when it wasn't set on entry can jump past state + // 0x10 or 0x08 and erroneously send uninitialized slave address. + if (isInterrupted) + i2c_clear_SI(obj); + i2c_wait_SI(obj); status = i2c_status(obj); - - // Clear start bit now transmitted, and interrupt bit + + // Clear start bit now that it's transmitted i2c_conclr(obj, 1, 0, 0, 0); return status; } diff --git a/hal/targets/hal/TARGET_NXP/TARGET_LPC23XX/i2c_api.c b/hal/targets/hal/TARGET_NXP/TARGET_LPC23XX/i2c_api.c index f4bceb49698..e24978dcb22 100644 --- a/hal/targets/hal/TARGET_NXP/TARGET_LPC23XX/i2c_api.c +++ b/hal/targets/hal/TARGET_NXP/TARGET_LPC23XX/i2c_api.c @@ -111,20 +111,26 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { inline int i2c_start(i2c_t *obj) { int status = 0; + int isInterrupted = I2C_CONSET(obj) & (1 << 3); + // 8.1 Before master mode can be entered, I2CON must be initialised to: // - I2EN STA STO SI AA - - - // - 1 0 0 0 x - - + // - 1 0 0 x x - - // if AA = 0, it can't enter slave mode - i2c_conclr(obj, 1, 1, 1, 1); - + i2c_conclr(obj, 1, 1, 0, 1); + // The master mode may now be entered by setting the STA bit // this will generate a start condition when the bus becomes free i2c_conset(obj, 1, 0, 0, 1); - + // Clearing SI bit when it wasn't set on entry can jump past state + // 0x10 or 0x08 and erroneously send uninitialized slave address. + if (isInterrupted) + i2c_clear_SI(obj); + i2c_wait_SI(obj); status = i2c_status(obj); - - // Clear start bit now transmitted, and interrupt bit + + // Clear start bit now that it's transmitted i2c_conclr(obj, 1, 0, 0, 0); return status; } diff --git a/hal/targets/hal/TARGET_NXP/TARGET_LPC2460/i2c_api.c b/hal/targets/hal/TARGET_NXP/TARGET_LPC2460/i2c_api.c index e8bead1248a..e497eea83a4 100644 --- a/hal/targets/hal/TARGET_NXP/TARGET_LPC2460/i2c_api.c +++ b/hal/targets/hal/TARGET_NXP/TARGET_LPC2460/i2c_api.c @@ -117,20 +117,26 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { inline int i2c_start(i2c_t *obj) { int status = 0; + int isInterrupted = I2C_CONSET(obj) & (1 << 3); + // 8.1 Before master mode can be entered, I2CON must be initialised to: // - I2EN STA STO SI AA - - - // - 1 0 0 0 x - - + // - 1 0 0 x x - - // if AA = 0, it can't enter slave mode - i2c_conclr(obj, 1, 1, 1, 1); - + i2c_conclr(obj, 1, 1, 0, 1); + // The master mode may now be entered by setting the STA bit // this will generate a start condition when the bus becomes free i2c_conset(obj, 1, 0, 0, 1); - + // Clearing SI bit when it wasn't set on entry can jump past state + // 0x10 or 0x08 and erroneously send uninitialized slave address. + if (isInterrupted) + i2c_clear_SI(obj); + i2c_wait_SI(obj); status = i2c_status(obj); - - // Clear start bit now transmitted, and interrupt bit + + // Clear start bit now that it's transmitted i2c_conclr(obj, 1, 0, 0, 0); return status; } diff --git a/hal/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/i2c_api.c b/hal/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/i2c_api.c index eaa103a5853..730e51eb49b 100644 --- a/hal/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/i2c_api.c +++ b/hal/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088/i2c_api.c @@ -133,20 +133,26 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { inline int i2c_start(i2c_t *obj) { int status = 0; + int isInterrupted = I2C_CONSET(obj) & (1 << 3); + // 8.1 Before master mode can be entered, I2CON must be initialised to: // - I2EN STA STO SI AA - - - // - 1 0 0 0 x - - + // - 1 0 0 x x - - // if AA = 0, it can't enter slave mode - i2c_conclr(obj, 1, 1, 1, 1); - + i2c_conclr(obj, 1, 1, 0, 1); + // The master mode may now be entered by setting the STA bit // this will generate a start condition when the bus becomes free i2c_conset(obj, 1, 0, 0, 1); - + // Clearing SI bit when it wasn't set on entry can jump past state + // 0x10 or 0x08 and erroneously send uninitialized slave address. + if (isInterrupted) + i2c_clear_SI(obj); + i2c_wait_SI(obj); status = i2c_status(obj); - - // Clear start bit now transmitted, and interrupt bit + + // Clear start bit now that it's transmitted i2c_conclr(obj, 1, 0, 0, 0); return status; } diff --git a/hal/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/i2c_api.c b/hal/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/i2c_api.c index ef3b3ac8823..64ebe3cc1cb 100644 --- a/hal/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/i2c_api.c +++ b/hal/targets/hal/TARGET_NXP/TARGET_LPC408X/TARGET_LPC4088_DM/i2c_api.c @@ -119,20 +119,26 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { inline int i2c_start(i2c_t *obj) { int status = 0; + int isInterrupted = I2C_CONSET(obj) & (1 << 3); + // 8.1 Before master mode can be entered, I2CON must be initialised to: // - I2EN STA STO SI AA - - - // - 1 0 0 0 x - - + // - 1 0 0 x x - - // if AA = 0, it can't enter slave mode - i2c_conclr(obj, 1, 1, 1, 1); + i2c_conclr(obj, 1, 1, 0, 1); // The master mode may now be entered by setting the STA bit // this will generate a start condition when the bus becomes free i2c_conset(obj, 1, 0, 0, 1); + // Clearing SI bit when it wasn't set on entry can jump past state + // 0x10 or 0x08 and erroneously send uninitialized slave address. + if (isInterrupted) + i2c_clear_SI(obj); i2c_wait_SI(obj); status = i2c_status(obj); - // Clear start bit now transmitted, and interrupt bit + // Clear start bit now that it's transmitted i2c_conclr(obj, 1, 0, 0, 0); return status; } diff --git a/hal/targets/hal/TARGET_NXP/TARGET_LPC43XX/i2c_api.c b/hal/targets/hal/TARGET_NXP/TARGET_LPC43XX/i2c_api.c index 5515e85e844..0e26102c911 100644 --- a/hal/targets/hal/TARGET_NXP/TARGET_LPC43XX/i2c_api.c +++ b/hal/targets/hal/TARGET_NXP/TARGET_LPC43XX/i2c_api.c @@ -113,20 +113,26 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl) { inline int i2c_start(i2c_t *obj) { int status = 0; + int isInterrupted = I2C_CONSET(obj) & (1 << 3); + // 8.1 Before master mode can be entered, I2CON must be initialised to: // - I2EN STA STO SI AA - - - // - 1 0 0 0 x - - + // - 1 0 0 x x - - // if AA = 0, it can't enter slave mode - i2c_conclr(obj, 1, 1, 1, 1); - + i2c_conclr(obj, 1, 1, 0, 1); + // The master mode may now be entered by setting the STA bit // this will generate a start condition when the bus becomes free i2c_conset(obj, 1, 0, 0, 1); - + // Clearing SI bit when it wasn't set on entry can jump past state + // 0x10 or 0x08 and erroneously send uninitialized slave address. + if (isInterrupted) + i2c_clear_SI(obj); + i2c_wait_SI(obj); status = i2c_status(obj); - - // Clear start bit now transmitted, and interrupt bit + + // Clear start bit now that it's transmitted i2c_conclr(obj, 1, 0, 0, 0); return status; } From 709f479093f2d124a4701bf9573736b623351286 Mon Sep 17 00:00:00 2001 From: 0xc0170 Date: Wed, 25 May 2016 13:34:28 +0100 Subject: [PATCH 07/87] hal - adding doxygen documentation The most doxygen docs are taken from ARMmbed/mbed-hal module. --- hal/hal/analogin_api.h | 31 +++++++++++++- hal/hal/analogout_api.h | 58 ++++++++++++++++++++++--- hal/hal/gpio_api.h | 85 +++++++++++++++++++++++++++++++++--- hal/hal/gpio_irq_api.h | 47 +++++++++++++++++++- hal/hal/i2c_api.h | 95 ++++++++++++++++++++++++----------------- hal/hal/lp_ticker_api.h | 2 +- hal/hal/port_api.h | 54 +++++++++++++++++++++-- hal/hal/pwmout_api.h | 86 ++++++++++++++++++++++++++++++++----- hal/hal/rtc_api.h | 30 +++++++++++++ hal/hal/serial_api.h | 54 +++++++++++------------ hal/hal/spi_api.h | 28 ++++++------ hal/hal/ticker_api.h | 24 +++++++---- hal/hal/us_ticker_api.h | 2 +- 13 files changed, 475 insertions(+), 121 deletions(-) diff --git a/hal/hal/analogin_api.h b/hal/hal/analogin_api.h index 98d02c1b825..f8d51176b4d 100644 --- a/hal/hal/analogin_api.h +++ b/hal/hal/analogin_api.h @@ -24,12 +24,39 @@ extern "C" { #endif +/** Analogin hal structure. analogin_s is declared in the target's hal + */ typedef struct analogin_s analogin_t; -void analogin_init (analogin_t *obj, PinName pin); -float analogin_read (analogin_t *obj); +/** + * \defgroup hal_analogin Analogin hal functions + * @{ + */ + +/** Initialize the analogin peripheral + * + * Configures the pin used by analogin. + * @param obj The analogin object to initialize + * @param pin The analogin pin name + */ +void analogin_init(analogin_t *obj, PinName pin); + +/** Read the input voltage, represented as a float in the range [0.0, 1.0] + * + * @param obj The analogin object + * @return A floating value representing the current input voltage + */ +float analogin_read(analogin_t *obj); + +/** Read the value from analogin pin, represented as an unsigned 16bit value + * + * @param obj The analogin object + * @return An unsigned 16bit value representing the current input voltage + */ uint16_t analogin_read_u16(analogin_t *obj); +/**@}*/ + #ifdef __cplusplus } #endif diff --git a/hal/hal/analogout_api.h b/hal/hal/analogout_api.h index 97a20137626..71c1222b151 100644 --- a/hal/hal/analogout_api.h +++ b/hal/hal/analogout_api.h @@ -24,14 +24,60 @@ extern "C" { #endif +/** Analogout hal structure. dac_s is declared in the target's hal + */ typedef struct dac_s dac_t; -void analogout_init (dac_t *obj, PinName pin); -void analogout_free (dac_t *obj); -void analogout_write (dac_t *obj, float value); -void analogout_write_u16(dac_t *obj, uint16_t value); -float analogout_read (dac_t *obj); -uint16_t analogout_read_u16 (dac_t *obj); +/** + * \defgroup hal_analogout Analogout hal functions + * @{ + */ + +/** Initialize the analogout peripheral + * + * Configures the pin used by analogout. + * @param obj The analogout object to initialize + * @param pin The analogout pin name + */ +void analogout_init(dac_t *obj, PinName pin); + +/** Release the analogout object + * + * Note: This is not currently used in the mbed-drivers + * @param obj The analogout object + */ +void analogout_free(dac_t *obj); + +/** Set the output voltage, specified as a percentage (float) + * + * @param obj The analogin object + * @param value The floating-point output voltage to be set + */ +void analogout_write(dac_t *obj, float value); + +/** Set the output voltage, specified as unsigned 16-bit + * + * @param obj The analogin object + * @param value The unsigned 16-bit output voltage to be set + */ +void analogout_write_u16(dac_t *obj, uint16_t value); + +/** Read the current voltage value on the pin + * + * @param obj The analogin object + * @return A floating-point value representing the current voltage on the pin, + * measured as a percentage + */ +float analogout_read(dac_t *obj); + +/** Read the current voltage value on the pin, as a normalized unsigned 16bit value + * + * @param obj The analogin object + * @return An unsigned 16-bit value representing the current voltage on the pin + */ +uint16_t analogout_read_u16(dac_t *obj); + +/**@}*/ #ifdef __cplusplus } diff --git a/hal/hal/gpio_api.h b/hal/hal/gpio_api.h index 872b547eaa1..4b4e45a7c27 100644 --- a/hal/hal/gpio_api.h +++ b/hal/hal/gpio_api.h @@ -16,40 +16,111 @@ #ifndef MBED_GPIO_API_H #define MBED_GPIO_API_H +#include #include "device.h" #ifdef __cplusplus extern "C" { #endif -/* Set the given pin as GPIO +/** + * \defgroup hal_gpio GPIO HAL functions + * @{ + */ + +/** Set the given pin as GPIO + * * @param pin The pin to be set as GPIO * @return The GPIO port mask for this pin **/ uint32_t gpio_set(PinName pin); - /* Checks if gpio object is connected (pin was not initialized with NC) * @param pin The pin to be set as GPIO * @return 0 if port is initialized with NC **/ int gpio_is_connected(const gpio_t *obj); -/* GPIO object */ +/** Initialize the GPIO pin + * + * @param obj The GPIO object to initialize + * @param pin The GPIO pin to initialize + */ void gpio_init(gpio_t *obj, PinName pin); -void gpio_mode (gpio_t *obj, PinMode mode); -void gpio_dir (gpio_t *obj, PinDirection direction); +/** Set the input pin mode + * + * @param obj The GPIO object + * @param mode The pin mode to be set + */ +void gpio_mode(gpio_t *obj, PinMode mode); + +/** Set the pin direction + * + * @param obj The GPIO object + * @param direction The pin direction to be set + */ +void gpio_dir(gpio_t *obj, PinDirection direction); +/** Set the output value + * + * @param obj The GPIO object + * @param value The value to be set + */ void gpio_write(gpio_t *obj, int value); -int gpio_read (gpio_t *obj); -// the following set of functions are generic and are implemented in the common gpio.c file +/** Read the input value + * + * @param obj The GPIO object + * @return An integer value 1 or 0 + */ +int gpio_read(gpio_t *obj); + +// the following functions are generic and implemented in the common gpio.c file +// TODO: fix, will be moved to the common gpio header file + +/** Init the input pin and set mode to PullDefault + * + * @param obj The GPIO object + * @param pin The pin name + */ void gpio_init_in(gpio_t* gpio, PinName pin); + +/** Init the input pin and set the mode + * + * @param obj The GPIO object + * @param pin The pin name + * @param mode The pin mode to be set + */ void gpio_init_in_ex(gpio_t* gpio, PinName pin, PinMode mode); + +/** Init the output pin as an output, with predefined output value 0 + * + * @param obj The GPIO object + * @param pin The pin name + * @return An integer value 1 or 0 + */ void gpio_init_out(gpio_t* gpio, PinName pin); + +/** Init the pin as an output and set the output value + * + * @param obj The GPIO object + * @param pin The pin name + * @param value The value to be set + */ void gpio_init_out_ex(gpio_t* gpio, PinName pin, int value); + +/** Init the pin to be in/out + * + * @param obj The GPIO object + * @param pin The pin name + * @param direction The pin direction to be set + * @param mode The pin mode to be set + * @param value The value to be set for an output pin + */ void gpio_init_inout(gpio_t* gpio, PinName pin, PinDirection direction, PinMode mode, int value); +/**@}*/ + #ifdef __cplusplus } #endif diff --git a/hal/hal/gpio_irq_api.h b/hal/hal/gpio_irq_api.h index 76c7e927ec7..c724dd100c7 100644 --- a/hal/hal/gpio_irq_api.h +++ b/hal/hal/gpio_irq_api.h @@ -24,22 +24,65 @@ extern "C" { #endif +/** GPIO IRQ events + */ typedef enum { IRQ_NONE, IRQ_RISE, IRQ_FALL } gpio_irq_event; +/** GPIO IRQ HAL structure. gpio_irq_s is declared in the target's HAL + */ typedef struct gpio_irq_s gpio_irq_t; typedef void (*gpio_irq_handler)(uint32_t id, gpio_irq_event event); -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id); +/** + * \defgroup hal_gpioirq GPIO IRQ HAL functions + * @{ + */ + +/** Initialize the GPIO IRQ pin + * + * @param obj The GPIO object to initialize + * @param pin The GPIO pin name + * @param handler The handler to be attached to GPIO IRQ + * @param id The object ID (id != 0, 0 is reserved) + * @return -1 if pin is NC, 0 otherwise + */ +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id); + +/** Release the GPIO IRQ PIN + * + * @param obj The gpio object + */ void gpio_irq_free(gpio_irq_t *obj); -void gpio_irq_set (gpio_irq_t *obj, gpio_irq_event event, uint32_t enable); + +/** Enable/disable pin IRQ event + * + * @param obj The GPIO object + * @param event The GPIO IRQ event + * @param enable The enable flag + */ +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable); + +/** Enable GPIO IRQ + * + * This is target dependent, as it might enable the entire port or just a pin + * @param obj The GPIO object + */ void gpio_irq_enable(gpio_irq_t *obj); + +/** Disable GPIO IRQ + * + * This is target dependent, as it might disable the entire port or just a pin + * @param obj The GPIO object + */ void gpio_irq_disable(gpio_irq_t *obj); +/**@}*/ + #ifdef __cplusplus } #endif diff --git a/hal/hal/i2c_api.h b/hal/hal/i2c_api.h index 22374071c04..68eae512f8b 100644 --- a/hal/hal/i2c_api.h +++ b/hal/hal/i2c_api.h @@ -18,12 +18,15 @@ #include "device.h" #include "buffer.h" + +#if DEVICE_I2C_ASYNCH #include "dma_api.h" +#endif #if DEVICE_I2C /** - * @defgroup I2CEvents I2C Events Macros + * @defgroup hal_I2CEvents I2C Events Macros * * @{ */ @@ -36,16 +39,16 @@ /**@}*/ #if DEVICE_I2C_ASYNCH -/** Asynch i2c hal structure +/** Asynch I2C HAL structure */ typedef struct { - struct i2c_s i2c; /**< Target specific i2c structure */ + struct i2c_s i2c; /**< Target specific I2C structure */ struct buffer_s tx_buff; /**< Tx buffer */ struct buffer_s rx_buff; /**< Rx buffer */ } i2c_t; #else -/** Non-asynch i2c hal structure +/** Non-asynch I2C HAL structure */ typedef struct i2c_s i2c_t; @@ -61,72 +64,81 @@ extern "C" { #endif /** - * \defgroup GeneralI2C I2C Configuration Functions + * \defgroup hal_GeneralI2C I2C Configuration Functions * @{ */ /** Initialize the I2C peripheral. It sets the default parameters for I2C - * peripheral, and configure its specifieds pins. - * @param obj The i2c object + * peripheral, and configures its specifieds pins. + * + * @param obj The I2C object * @param sda The sda pin * @param scl The scl pin */ void i2c_init(i2c_t *obj, PinName sda, PinName scl); -/** Configure the I2C frequency. - * @param obj The i2c object +/** Configure the I2C frequency + * + * @param obj The I2C object * @param hz Frequency in Hz */ void i2c_frequency(i2c_t *obj, int hz); -/** Send START command. - * @param obj The i2c object +/** Send START command + * + * @param obj The I2C object */ int i2c_start(i2c_t *obj); -/** Send STOP command. - * @param obj The i2c object +/** Send STOP command + * + * @param obj The I2C object */ int i2c_stop(i2c_t *obj); -/** Blocking reading data. - * @param obj The i2c object +/** Blocking reading data + * + * @param obj The I2C object * @param address 7-bit address (last bit is 1) * @param data The buffer for receiving * @param length Number of bytes to read * @param stop Stop to be generated after the transfer is done * @return Number of read bytes */ -int i2c_read(i2c_t *obj, int address, char *data, int length, int stop); +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop); -/** Blocking sending data. - * @param obj The i2c object +/** Blocking sending data + * + * @param obj The I2C object * @param address 7-bit address (last bit is 0) * @param data The buffer for sending - * @param length Number of bytes to wrte + * @param length Number of bytes to write * @param stop Stop to be generated after the transfer is done * @return Number of written bytes */ -int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop); +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop); -/** Reset I2C peripheral. TODO: The action here. Most of the implementation sends stop(). - * @param obj The i2c object +/** Reset I2C peripheral. TODO: The action here. Most of the implementation sends stop() + * + * @param obj The I2C object */ void i2c_reset(i2c_t *obj); -/** Read one byte. - * @param obj The i2c object +/** Read one byte + * + * @param obj The I2C object * @param last Acknoledge * @return The read byte */ -int i2c_byte_read(i2c_t *obj, int last); +int i2c_byte_read(i2c_t *obj, int last); -/** Write one byte. - * @param obj The i2c object +/** Write one byte + * + * @param obj The I2C object * @param data Byte to be written * @return 0 if NAK was received, 1 if ACK was received, 2 for timeout. */ -int i2c_byte_write(i2c_t *obj, int data); +int i2c_byte_write(i2c_t *obj, int data); /**@}*/ @@ -177,17 +189,18 @@ void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask); #if DEVICE_I2C_ASYNCH /** - * \defgroup AsynchI2C Asynchronous I2C Hardware Abstraction Layer + * \defgroup hal_AsynchI2C Asynchronous I2C Hardware Abstraction Layer * @{ */ -/** Start i2c asynchronous transfer. +/** Start I2C asynchronous transfer + * * @param obj The I2C object - * @param tx The buffer to send - * @param tx_length The number of words to transmit - * @param rx The buffer to receive - * @param rx_length The number of words to receive - * @param address The address to be set - 7bit or 9 bit + * @param tx The transmit buffer + * @param tx_length The number of bytes to transmit + * @param rx The receive buffer + * @param rx_length The number of bytes to receive + * @param address The address to be set - 7bit or 9bit * @param stop If true, stop will be generated after the transfer is done * @param handler The I2C IRQ handler to be set * @param hint DMA hint usage @@ -195,18 +208,22 @@ void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask); void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint); /** The asynchronous IRQ handler + * * @param obj The I2C object which holds the transfer information - * @return event flags if a transfer termination condition was met or 0 otherwise. + * @return Event flags if a transfer termination condition was met, otherwise return 0. */ uint32_t i2c_irq_handler_asynch(i2c_t *obj); -/** Attempts to determine if I2C peripheral is already in use. +/** Attempts to determine if the I2C peripheral is already in use + * * @param obj The I2C object - * @return non-zero if the I2C module is active or zero if it is not + * @return Non-zero if the I2C module is active or zero if it is not */ uint8_t i2c_active(i2c_t *obj); -/** Abort ongoing asynchronous transaction. +/** Abort asynchronous transfer + * + * This function does not perform any check - that should happen in upper layers. * @param obj The I2C object */ void i2c_abort_asynch(i2c_t *obj); diff --git a/hal/hal/lp_ticker_api.h b/hal/hal/lp_ticker_api.h index 7e652ea1bcf..aae5a3f3657 100644 --- a/hal/hal/lp_ticker_api.h +++ b/hal/hal/lp_ticker_api.h @@ -27,7 +27,7 @@ extern "C" { #endif /** - * \defgroup LpTicker Low Power Ticker Functions + * \defgroup hal_LpTicker Low Power Ticker Functions * @{ */ diff --git a/hal/hal/port_api.h b/hal/hal/port_api.h index f687cfe89a2..15babe0db63 100644 --- a/hal/hal/port_api.h +++ b/hal/hal/port_api.h @@ -24,15 +24,61 @@ extern "C" { #endif +/** Port HAL structure. port_s is declared in the target's HAL + */ typedef struct port_s port_t; +/** + * \defgroup hal_port Port HAL functions + * @{ + */ + +/** Get the pin name from the port's pin number + * + * @param port The port name + * @param pin_n The pin number within the specified port + * @return The pin name for the port's pin number + */ PinName port_pin(PortName port, int pin_n); -void port_init (port_t *obj, PortName port, int mask, PinDirection dir); -void port_mode (port_t *obj, PinMode mode); -void port_dir (port_t *obj, PinDirection dir); +/** Initilize the port + * + * @param obj The port object to initialize + * @param port The port name + * @param mask The bitmask to identify which bits in the port should be included (0 - ignore) + * @param dir The port direction + */ +void port_init(port_t *obj, PortName port, int mask, PinDirection dir); + +/** Set the input port mode + * + * @param obj The port object + * @param mode THe port mode to be set + */ +void port_mode(port_t *obj, PinMode mode); + +/** Set port direction (in/out) + * + * @param obj The port object + * @param dir The port direction to be set + */ +void port_dir(port_t *obj, PinDirection dir); + +/** Write value to the port + * + * @param obj The port object + * @param value The value to be set + */ void port_write(port_t *obj, int value); -int port_read (port_t *obj); + +/** Read the current value on the port + * + * @param obj The port object + * @return An integer with each bit corresponding to an associated port pin setting + */ +int port_read(port_t *obj); + +/**@}*/ #ifdef __cplusplus } diff --git a/hal/hal/pwmout_api.h b/hal/hal/pwmout_api.h index 6557fcdc49c..a18f853b2cd 100644 --- a/hal/hal/pwmout_api.h +++ b/hal/hal/pwmout_api.h @@ -24,21 +24,87 @@ extern "C" { #endif +/** Pwmout hal structure. pwmout_s is declared in the target's hal + */ typedef struct pwmout_s pwmout_t; -void pwmout_init (pwmout_t* obj, PinName pin); -void pwmout_free (pwmout_t* obj); +/** + * \defgroup hal_pwmout Pwmout hal functions + * @{ + */ + +/** Initialize the pwm out peripheral and configure the pin + * + * @param obj The pwmout object to initialize + * @param pin The pwmout pin to initialize + */ +void pwmout_init(pwmout_t *obj, PinName pin); + +/** Deinitialize the pwmout object + * + * @param obj The pwmout object + */ +void pwmout_free(pwmout_t *obj); + +/** Set the output duty-cycle in range <0.0f, 1.0f> + * + * Value 0.0f represents 0 percentage, 1.0f represents 100 percent. + * @param obj The pwmout object + * @param percent The floating-point percentage number + */ +void pwmout_write(pwmout_t *obj, float percent); + +/** Read the current float-point output duty-cycle + * + * @param obj The pwmout object + * @return A floating-point output duty-cycle + */ +float pwmout_read(pwmout_t *obj); + +/** Set the PWM period specified in seconds, keeping the duty cycle the same + * + * Periods smaller than microseconds (the lowest resolution) are set to zero. + * @param obj The pwmout object + * @param seconds The floating-point seconds period + */ +void pwmout_period(pwmout_t *obj, float seconds); + +/** Set the PWM period specified in miliseconds, keeping the duty cycle the same + * + * @param obj The pwmout object + * @param ms The milisecond period + */ +void pwmout_period_ms(pwmout_t *obj, int ms); -void pwmout_write (pwmout_t* obj, float percent); -float pwmout_read (pwmout_t* obj); +/** Set the PWM period specified in microseconds, keeping the duty cycle the same + * + * @param obj The pwmout object + * @param us The microsecond period + */ +void pwmout_period_us(pwmout_t *obj, int us); -void pwmout_period (pwmout_t* obj, float seconds); -void pwmout_period_ms (pwmout_t* obj, int ms); -void pwmout_period_us (pwmout_t* obj, int us); +/** Set the PWM pulsewidth specified in seconds, keeping the period the same. + * + * @param obj The pwmout object + * @param seconds The floating-point pulsewidth in seconds + */ +void pwmout_pulsewidth(pwmout_t *obj, float seconds); + +/** Set the PWM pulsewidth specified in miliseconds, keeping the period the same. + * + * @param obj The pwmout object + * @param ms The floating-point pulsewidth in miliseconds + */ +void pwmout_pulsewidth_ms(pwmout_t *obj, int ms); + +/** Set the PWM pulsewidth specified in microseconds, keeping the period the same. + * + * @param obj The pwmout object + * @param us The floating-point pulsewidth in microseconds + */ +void pwmout_pulsewidth_us(pwmout_t *obj, int us); -void pwmout_pulsewidth (pwmout_t* obj, float seconds); -void pwmout_pulsewidth_ms(pwmout_t* obj, int ms); -void pwmout_pulsewidth_us(pwmout_t* obj, int us); +/**@}*/ #ifdef __cplusplus } diff --git a/hal/hal/rtc_api.h b/hal/hal/rtc_api.h index 663f8884fec..94bfe4f0bc0 100644 --- a/hal/hal/rtc_api.h +++ b/hal/hal/rtc_api.h @@ -26,13 +26,43 @@ extern "C" { #endif +/** + * \defgroup hal_rtc RTC hal functions + * @{ + */ + +/** Initialize the RTC peripheral + * + */ void rtc_init(void); + +/** Deinitialize RTC + * + * TODO: The function is not used by rtc api in mbed-drivers. + */ void rtc_free(void); + +/** Get the RTC enable status + * + * @retval 0 disabled + * @retval 1 enabled + */ int rtc_isenabled(void); +/** Get the current time from the RTC peripheral + * + * @return The current time + */ time_t rtc_read(void); + +/** Set the current time to the RTC peripheral + * + * @param t The current time to be set + */ void rtc_write(time_t t); +/**@}*/ + #ifdef __cplusplus } #endif diff --git a/hal/hal/serial_api.h b/hal/hal/serial_api.h index 6cf9a4bb5a3..16d3699ab0e 100644 --- a/hal/hal/serial_api.h +++ b/hal/hal/serial_api.h @@ -80,18 +80,18 @@ typedef enum { typedef void (*uart_irq_handler)(uint32_t id, SerialIrq event); #if DEVICE_SERIAL_ASYNCH -/** Asynch serial hal structure +/** Asynch serial HAL structure */ typedef struct { struct serial_s serial; /**< Target specific serial structure */ - struct buffer_s tx_buff; /**< Tx buffer */ - struct buffer_s rx_buff; /**< Rx buffer */ + struct buffer_s tx_buff; /**< TX buffer */ + struct buffer_s rx_buff; /**< RX buffer */ uint8_t char_match; /**< Character to be matched */ uint8_t char_found; /**< State of the matched character */ } serial_t; #else -/** Non-asynch serial hal structure +/** Non-asynch serial HAL structure */ typedef struct serial_s serial_t; @@ -102,16 +102,16 @@ extern "C" { #endif /** - * \defgroup GeneralSerial Serial Configuration Functions + * \defgroup hal_GeneralSerial Serial Configuration Functions * @{ */ /** Initialize the serial peripheral. It sets the default parameters for serial - * peripheral, and configure its specifieds pins. + * peripheral, and configures its specifieds pins. * * @param obj The serial object - * @param tx The TX pin - * @param rx The RX pin + * @param tx The TX pin name + * @param rx The RX pin name */ void serial_init(serial_t *obj, PinName tx, PinName rx); @@ -138,10 +138,10 @@ void serial_baud(serial_t *obj, int baudrate); */ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits); -/** The serial interrupt handler registration. +/** The serial interrupt handler registration * * @param obj The serial object - * @param handler The interrupt handler which will be invoked when interrupt fires. + * @param handler The interrupt handler which will be invoked when the interrupt fires * @param id The SerialBase object */ void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id); @@ -160,7 +160,7 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable); */ int serial_getc(serial_t *obj); -/** Put a character. This is a blocking call, waiting for a peripheral to be available +/** Send a character. This is a blocking call, waiting for a peripheral to be available * for writing * * @param obj The serial object @@ -171,7 +171,7 @@ void serial_putc(serial_t *obj, int c); /** Check if the serial peripheral is readable * * @param obj The serial object - * @return Non-zero value if a character can be read, 0 if nothing to read. + * @return Non-zero value if a character can be read, 0 if nothing to read */ int serial_readable(serial_t *obj); @@ -202,7 +202,7 @@ void serial_break_clear(serial_t *obj); /** Configure the TX pin for UART function. * - * @param tx The pin used for TX + * @param tx The pin name used for TX */ void serial_pinout_tx(PinName tx); @@ -211,8 +211,8 @@ void serial_pinout_tx(PinName tx); * * @param obj The serial object * @param type The type of the flow control. Look at the available FlowControl types. - * @param rxflow The tx pin - * @param txflow The rx pin + * @param rxflow The TX pin name + * @param txflow The RX pin name */ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow); @@ -221,7 +221,7 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi /**@}*/ /** - * \defgroup AsynchSerial Asynchronous Serial Hardware Abstraction Layer + * \defgroup hal_AsynchSerial Asynchronous Serial Hardware Abstraction Layer * @{ */ @@ -229,13 +229,13 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi * tx_buff * * @param obj The serial object - * @param tx The buffer for sending - * @param tx_length The number of words to transmit - * @param tx_width The bit width of buffer word + * @param tx The transmit buffer + * @param tx_length The number of bytes to transmit + * @param tx_width Deprecated argument * @param handler The serial handler * @param event The logical OR of events to be registered * @param hint A suggestion for how to use DMA with this transfer - * @return Returns number of data transfered, or 0 otherwise + * @return Returns number of data transfered, otherwise returns 0 */ int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx_width, uint32_t handler, uint32_t event, DMAUsage hint); @@ -243,9 +243,9 @@ int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx * The used buffer is specified in the serial object - rx_buff * * @param obj The serial object - * @param rx The buffer for sending - * @param rx_length The number of words to transmit - * @param rx_width The bit width of buffer word + * @param rx The receive buffer + * @param rx_length The number of bytes to receive + * @param rx_width Deprecated argument * @param handler The serial handler * @param event The logical OR of events to be registered * @param handler The serial handler @@ -271,19 +271,19 @@ uint8_t serial_rx_active(serial_t *obj); /** The asynchronous TX and RX handler. * * @param obj The serial object - * @return Returns event flags if a RX transfer termination condition was met or 0 otherwise + * @return Returns event flags if an RX transfer termination condition was met; otherwise returns 0 */ int serial_irq_handler_asynch(serial_t *obj); /** Abort the ongoing TX transaction. It disables the enabled interupt for TX and - * flush TX hardware buffer if TX FIFO is used + * flushes the TX hardware buffer if TX FIFO is used * * @param obj The serial object */ void serial_tx_abort_asynch(serial_t *obj); -/** Abort the ongoing RX transaction It disables the enabled interrupt for RX and - * flush RX hardware buffer if RX FIFO is used +/** Abort the ongoing RX transaction. It disables the enabled interrupt for RX and + * flushes the RX hardware buffer if RX FIFO is used * * @param obj The serial object */ diff --git a/hal/hal/spi_api.h b/hal/hal/spi_api.h index 16ec74dab17..00bd6873c77 100644 --- a/hal/hal/spi_api.h +++ b/hal/hal/spi_api.h @@ -27,21 +27,21 @@ #define SPI_EVENT_RX_OVERFLOW (1 << 3) #define SPI_EVENT_ALL (SPI_EVENT_ERROR | SPI_EVENT_COMPLETE | SPI_EVENT_RX_OVERFLOW) -#define SPI_EVENT_INTERNAL_TRANSFER_COMPLETE (1 << 30) // internal flag to report an event occurred +#define SPI_EVENT_INTERNAL_TRANSFER_COMPLETE (1 << 30) // Internal flag to report that an event occurred #define SPI_FILL_WORD (0xFFFF) #if DEVICE_SPI_ASYNCH -/** Asynch spi hal structure +/** Asynch SPI HAL structure */ typedef struct { - struct spi_s spi; /**< Target specific spi structure */ + struct spi_s spi; /**< Target specific SPI structure */ struct buffer_s tx_buff; /**< Tx buffer */ struct buffer_s rx_buff; /**< Rx buffer */ } spi_t; #else -/** Non-asynch spi hal structure +/** Non-asynch SPI HAL structure */ typedef struct spi_s spi_t; @@ -52,7 +52,7 @@ extern "C" { #endif /** - * \defgroup GeneralSPI SPI Configuration Functions + * \defgroup hal_GeneralSPI SPI Configuration Functions * @{ */ @@ -159,11 +159,11 @@ uint8_t spi_get_module(spi_t *obj); /** Begin the SPI transfer. Buffer pointers and lengths are specified in tx_buff and rx_buff * - * @param[in] obj The SPI object which holds the transfer information - * @param[in] tx The buffer to send - * @param[in] tx_length The number of words to transmit - * @param[in] rx The buffer to receive - * @param[in] rx_length The number of words to receive + * @param[in] obj The SPI object that holds the transfer information + * @param[in] tx The transmit buffer + * @param[in] tx_length The number of bytes to transmit + * @param[in] rx The receive buffer + * @param[in] rx_length The number of bytes to receive * @param[in] bit_width The bit width of buffer words * @param[in] event The logical OR of events to be registered * @param[in] handler SPI interrupt handler @@ -175,12 +175,12 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, * * Reads the received values out of the RX FIFO, writes values into the TX FIFO and checks for transfer termination * conditions, such as buffer overflows or transfer complete. - * @param[in] obj The SPI object which holds the transfer information - * @return event flags if a transfer termination condition was met or 0 otherwise. + * @param[in] obj The SPI object that holds the transfer information + * @return Event flags if a transfer termination condition was met; otherwise 0. */ uint32_t spi_irq_handler_asynch(spi_t *obj); -/** Attempts to determine if the SPI peripheral is already in use. +/** Attempts to determine if the SPI peripheral is already in use * * If a temporary DMA channel has been allocated, peripheral is in use. * If a permanent DMA channel has been allocated, check if the DMA channel is in use. If not, proceed as though no DMA @@ -189,7 +189,7 @@ uint32_t spi_irq_handler_asynch(spi_t *obj); * if the corresponding buffer position is less than the buffer length. If buffers do not indicate activity, check if * there are any bytes in the FIFOs. * @param[in] obj The SPI object to check for activity - * @return non-zero if the SPI port is active or zero if it is not. + * @return Non-zero if the SPI port is active or zero if it is not. */ uint8_t spi_active(spi_t *obj); diff --git a/hal/hal/ticker_api.h b/hal/hal/ticker_api.h index 5f24d27a4cf..52fb3edb0da 100644 --- a/hal/hal/ticker_api.h +++ b/hal/hal/ticker_api.h @@ -16,6 +16,7 @@ #ifndef MBED_TICKER_API_H #define MBED_TICKER_API_H +#include #include "device.h" typedef uint32_t timestamp_t; @@ -40,32 +41,37 @@ typedef struct { void (*set_interrupt)(timestamp_t timestamp); /**< Set interrupt function */ } ticker_interface_t; -/** Tickers events queue structure +/** Ticker's event queue structure */ typedef struct { ticker_event_handler event_handler; /**< Event handler */ ticker_event_t *head; /**< A pointer to head */ } ticker_event_queue_t; -/** Tickers data structure +/** Ticker's data structure */ typedef struct { const ticker_interface_t *interface; /**< Ticker's interface */ - ticker_event_queue_t *queue; /**< Ticker's events queue */ + ticker_event_queue_t *queue; /**< Ticker's event queue */ } ticker_data_t; #ifdef __cplusplus extern "C" { #endif -/** Initialize a ticker and sets the event handler +/** + * \defgroup hal_ticker Ticker HAL functions + * @{ + */ + +/** Initialize a ticker and set the event handler * * @param data The ticker's data * @param handler A handler to be set */ void ticker_set_handler(const ticker_data_t *const data, ticker_event_handler handler); -/** Irq handler which goes through the events to trigger events in the past. +/** IRQ handler that goes through the events to trigger overdue events. * * @param data The ticker's data */ @@ -74,14 +80,14 @@ void ticker_irq_handler(const ticker_data_t *const data); /** Remove an event from the queue * * @param data The ticker's data - * @param obj The event's queue to be removed + * @param obj The event object to be removed from the queue */ void ticker_remove_event(const ticker_data_t *const data, ticker_event_t *obj); -/** Insert an event from the queue +/** Insert an event to the queue * * @param data The ticker's data - * @param obj The event's queue to be removed + * @param obj The event object to be inserted to the queue * @param timestamp The event's timestamp * @param id The event object */ @@ -101,6 +107,8 @@ timestamp_t ticker_read(const ticker_data_t *const data); */ int ticker_get_next_timestamp(const ticker_data_t *const data, timestamp_t *timestamp); +/**@}*/ + #ifdef __cplusplus } #endif diff --git a/hal/hal/us_ticker_api.h b/hal/hal/us_ticker_api.h index b5c78de582a..70bf4e09901 100644 --- a/hal/hal/us_ticker_api.h +++ b/hal/hal/us_ticker_api.h @@ -24,7 +24,7 @@ extern "C" { #endif /** - * \defgroup UsTicker Microseconds Ticker Functions + * \defgroup hal_UsTicker Microseconds Ticker Functions * @{ */ From 04e4c6a8808ec9137758b22051a798fbe9077fcc Mon Sep 17 00:00:00 2001 From: 0xc0170 Date: Fri, 27 May 2016 14:14:39 +0100 Subject: [PATCH 08/87] k64f - mac address - fix warnings - get UID via K64F SIM macros --- .../TARGET_K64F/TARGET_FRDM/mbed_overrides.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K64F/TARGET_FRDM/mbed_overrides.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K64F/TARGET_FRDM/mbed_overrides.c index f324d8310ee..3c62ed7ca4a 100644 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K64F/TARGET_FRDM/mbed_overrides.c +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K64F/TARGET_FRDM/mbed_overrides.c @@ -44,18 +44,19 @@ void rtc_setup_oscillator(RTC_Type *base) // Provide ethernet devices with a semi-unique MAC address from the UUID void mbed_mac_address(char *mac) { + uint16_t MAC[3]; // 3 16 bits words for the MAC - unsigned int UUID_LOC_BASE = 0x40048054; // First adddress of the 4-word UUID - char uuid[16]; // So we can take a local copy of the UUID - uint32_t MAC[3]; // 3 16 bits words for the MAC - - // copy the UUID to the variable MAC[] - memcpy(uuid,(const void*)UUID_LOC_BASE,sizeof(uuid)); + // get UID via SIM_UID macros defined in the K64F MCU CMSIS header file + uint32_t UID[4]; + UID[0] = SIM->UIDH; + UID[1] = SIM->UIDMH; + UID[2] = SIM->UIDML; + UID[3] = SIM->UIDL; // generate three CRC16's using different slices of the UUID - MAC[0] = crcSlow(uuid, 8); // most significant half-word - MAC[1] = crcSlow(uuid, 12); - MAC[2] = crcSlow(uuid, 16); // least significant half word + MAC[0] = crcSlow((const uint8_t *)UID, 8); // most significant half-word + MAC[1] = crcSlow((const uint8_t *)UID, 12); + MAC[2] = crcSlow((const uint8_t *)UID, 16); // least significant half word // The network stack expects an array of 6 bytes // so we copy, and shift and copy from the half-word array to the byte array From d8935bb837267b1c95cee7fbb5ddadc54be5b753 Mon Sep 17 00:00:00 2001 From: Anders Lindvall Date: Mon, 30 May 2016 10:50:17 +0200 Subject: [PATCH 09/87] Misc fixes for LPC4088/LPC4088DM: - Resetting in LPCXpresso IDE did not reset the LCD controller which sometimes could cause strange behaviour - The ROM_LAT bit in the MATRIXARB register must be set in order to prevent a HardFault when debugging - The change of compiler in LPCXpresso IDE to ARM launchpad GCC5 was causing build errors due to multiply defined timeval symbol. - The exporters for LPCXpresso IDE did not set the FPU_PRESENT define for assembler, only for c/c++. This caused very strange behaviour in the RTOS code (e.g. timeouts no longer working, context switches failing etc.) --- .../TARGET_NXP/TARGET_LPC408X/LPC407x_8x_177x_8x.h | 4 +++- .../TARGET_LPC408X/system_LPC407x_8x_177x_8x.c | 10 ++++++++++ .../net/eth/lwip-eth/arch/TARGET_NXP/lwipopts_conf.h | 6 ++++++ workspace_tools/export/codered_lpc4088_cproject.tmpl | 4 ++-- .../export/codered_lpc4088_dm_cproject.tmpl | 4 ++-- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/hal/targets/cmsis/TARGET_NXP/TARGET_LPC408X/LPC407x_8x_177x_8x.h b/hal/targets/cmsis/TARGET_NXP/TARGET_LPC408X/LPC407x_8x_177x_8x.h index 2a2220b0d86..c7ff650716a 100644 --- a/hal/targets/cmsis/TARGET_NXP/TARGET_LPC408X/LPC407x_8x_177x_8x.h +++ b/hal/targets/cmsis/TARGET_NXP/TARGET_LPC408X/LPC407x_8x_177x_8x.h @@ -209,7 +209,9 @@ typedef struct __IO uint32_t EXTPOLAR; /*!< Offset: 0x14C (R/W) External Interrupt Polarity Register */ uint32_t RESERVED6[12]; __IO uint32_t RSID; /*!< Offset: 0x180 (R/W) Reset Source Identification Register */ - uint32_t RESERVED7[7]; + uint32_t RESERVED7[1]; + __IO uint32_t MATRIXARB; /*!< Offset: 0x188 (R/W) Matrix Arbitration Register */ + uint32_t RESERVED71[5]; __IO uint32_t SCS; /*!< Offset: 0x1A0 (R/W) System Controls and Status Register */ __IO uint32_t IRCTRIM; /*!< Offset: 0x1A4 (R/W) Clock Dividers */ __IO uint32_t PCLKSEL; /*!< Offset: 0x1A8 (R/W) Peripheral Clock Selection Register */ diff --git a/hal/targets/cmsis/TARGET_NXP/TARGET_LPC408X/system_LPC407x_8x_177x_8x.c b/hal/targets/cmsis/TARGET_NXP/TARGET_LPC408X/system_LPC407x_8x_177x_8x.c index fbfe88bb20d..835d31b4a59 100644 --- a/hal/targets/cmsis/TARGET_NXP/TARGET_LPC408X/system_LPC407x_8x_177x_8x.c +++ b/hal/targets/cmsis/TARGET_NXP/TARGET_LPC408X/system_LPC407x_8x_177x_8x.c @@ -567,5 +567,15 @@ fpu_init(); SCB->VTOR = 0x00000000 & 0x3FFFFF80; #endif #endif + + /* Must set ROM_LAT bit in the Matrix Arbitration Register otherwise SPIFI + * initialization will cause debugging to HardFault */ + LPC_SC->MATRIXARB |= (1<<16); + + /* Reset LCD Controller to prevent strange behavior when doing a partial + * reset (happens when debugging). + */ + LPC_SC->RSTCON0 = 1; + SystemCoreClockUpdate(); } diff --git a/libraries/net/eth/lwip-eth/arch/TARGET_NXP/lwipopts_conf.h b/libraries/net/eth/lwip-eth/arch/TARGET_NXP/lwipopts_conf.h index a117fa6c93e..e78e3d258e0 100644 --- a/libraries/net/eth/lwip-eth/arch/TARGET_NXP/lwipopts_conf.h +++ b/libraries/net/eth/lwip-eth/arch/TARGET_NXP/lwipopts_conf.h @@ -27,4 +27,10 @@ #define MEM_SIZE 16362 #endif +#if defined (TOOLCHAIN_GCC_CR) + /* For LPCXpresso IDE above v8.0.0 to avoid clash with timeval struct */ + #include + #define LWIP_TIMEVAL_PRIVATE 0 +#endif + #endif diff --git a/workspace_tools/export/codered_lpc4088_cproject.tmpl b/workspace_tools/export/codered_lpc4088_cproject.tmpl index 9d3231cf80e..f394f40ae58 100644 --- a/workspace_tools/export/codered_lpc4088_cproject.tmpl +++ b/workspace_tools/export/codered_lpc4088_cproject.tmpl @@ -69,7 +69,7 @@