From ef79cf68a7f055743b6b6cb68b1c2e6a48af1015 Mon Sep 17 00:00:00 2001 From: Marc Moreno Berengue Date: Wed, 14 Jun 2017 10:16:47 +0100 Subject: [PATCH 1/5] Implement pin_function and gpio_set This patch implements pin_function and gpio_set with some fixes in the PinNames. The patch also updates the serial and spi drivers to use the pin_function. Signed-off-by: Marc Moreno --- .../TARGET_CM3DS_MPS2/PinNames.h | 357 +++++++++--------- .../TARGET_CM3DS_MPS2/gpio_api.c | 82 ++-- .../TARGET_ARM_SSG/TARGET_CM3DS_MPS2/pinmap.c | 24 +- .../TARGET_CM3DS_MPS2/serial_api.c | 118 ++---- .../TARGET_CM3DS_MPS2/spi_api.c | 161 +++----- 5 files changed, 328 insertions(+), 414 deletions(-) diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/PinNames.h b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/PinNames.h index 8ce5fd984c..7cbff11502 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/PinNames.h +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/PinNames.h @@ -30,201 +30,204 @@ typedef enum { #define PORT_SHIFT 5 typedef enum { - // MPS2 EXP Pin Names - EXP0 = 0 , - EXP1 = 4 , - EXP2 = 2 , - EXP3 = 3 , - EXP4 = 1 , - EXP5 = 15, - EXP6 = 5 , - EXP7 = 6 , - EXP8 = 7 , - EXP9 = 8 , - EXP10 =9 , - EXP11 =13, - EXP12 =10, - EXP13 =11, - EXP14 =12, - EXP15 =14, - EXP16 =18, - EXP17 =19, - EXP18 =20, - EXP19 =21, - EXP20 =52, - EXP21 =53, - EXP22 =54, - EXP23 =55, - EXP24 =56, - EXP25 =57, - - EXP26 =16, - EXP27 =25, - EXP28 =24, - EXP29 =31, - EXP30 =17, - EXP31 =23, - EXP32 =27, - EXP33 =30, - EXP34 =26, - EXP35 =28, - EXP36 =29, - EXP37 =58, - EXP38 =48, - EXP39 =49, - EXP40 =50, - EXP41 =22, - EXP42 =59, - EXP43 =60, - EXP44 =51, - EXP45 =61, - EXP46 =62, - EXP47 =63, - EXP48 =64, - EXP49 =65, - EXP50 =66, - EXP51 =67, + /* MPS2 EXP Pin Names */ + EXP0 = 0, + EXP1 = 1, + EXP2 = 2, + EXP3 = 3, + EXP4 = 4, + EXP5 = 5, + EXP6 = 6, + EXP7 = 7, + EXP8 = 8, + EXP9 = 9, + EXP10 = 10, + EXP11 = 11, + EXP12 = 12, + EXP13 = 13, + EXP14 = 14, + EXP15 = 15, + EXP16 = 16, + EXP17 = 17, + EXP18 = 18, + EXP19 = 19, + EXP20 = 20, + EXP21 = 21, + EXP22 = 22, + EXP23 = 23, + EXP24 = 24, + EXP25 = 25, + EXP26 = 26, + EXP27 = 27, + EXP28 = 28, + EXP29 = 29, + EXP30 = 30, + EXP31 = 31, + EXP32 = 32, + EXP33 = 33, + EXP34 = 34, + EXP35 = 35, + EXP36 = 36, + EXP37 = 37, + EXP38 = 38, + EXP39 = 39, + EXP40 = 40, + EXP41 = 41, + EXP42 = 42, + EXP43 = 43, + EXP44 = 44, + EXP45 = 45, + EXP46 = 46, + EXP47 = 47, + EXP48 = 48, + EXP49 = 49, + EXP50 = 50, + EXP51 = 51, // Other mbed Pin Names - //LEDs on mps2 - //user leds - USERLED1 = 100, - USERLED2 = 101, - //user switches - USERSW1 = 110, - USERSW2 = 111, + /* User leds */ + USERLED1 = 100, + USERLED2 = 101, + /* User switches */ + USERSW1 = 110, + USERSW2 = 111, - //mcc leds - LED1 = 200, - LED2 = 201, - LED3 = 202, - LED4 = 203, - LED5 = 204, - LED6 = 205, - LED7 = 206, - LED8 = 207, + /* MCC leds */ + LED1 = 200, + LED2 = 201, + LED3 = 202, + LED4 = 203, + LED5 = 204, + LED6 = 205, + LED7 = 206, + LED8 = 207, - //MCC Switches - SW1 = 210, - SW2 = 211, - SW3 = 212, - SW4 = 213, - SW5 = 214, - SW6 = 215, - SW7 = 216, - SW8 = 217, + /* MCC Switches */ + SW1 = 210, + SW2 = 211, + SW3 = 212, + SW4 = 213, + SW5 = 214, + SW6 = 215, + SW7 = 216, + SW8 = 217, - //MPS2 SPI header pins j21 - SPI_MOSI = 300, - SPI_MISO = 301, - SPI_SCLK = 302, - SPI_SSEL = 303, + /* MPS2 SPI header pins J21 */ + SPI_MOSI = 300, + SPI_MISO = 301, + SPI_SCLK = 302, + SPI_SSEL = 303, - //MPS2 CLCD SPI - CLCD_MOSI = 304, - CLCD_MISO = 305, - CLCD_SCLK = 306, - CLCD_SSEL = 307, - CLCD_RESET = 308, - CLCD_RS = 309, - CLCD_RD = 310, - CLCD_BL_CTRL = 311, + /* MPS2 CLCD SPI */ + CLCD_MOSI = 304, + CLCD_MISO = 305, + CLCD_SCLK = 306, + CLCD_SSEL = 307, + CLCD_RESET = 308, + CLCD_RS = 309, + CLCD_RD = 310, + CLCD_BL_CTRL = 311, - //MPS2 shield 0 SPI - SHIELD_0_SPI_SCK = 320, - SHIELD_0_SPI_MOSI = 321, - SHIELD_0_SPI_MISO = 322, - SHIELD_0_SPI_nCS = 323, + /* MPS2 shield 0 SPI */ + SHIELD_0_SPI_MOSI = EXP13, + SHIELD_0_SPI_MISO = EXP14, + SHIELD_0_SPI_SCK = EXP11, + SHIELD_0_SPI_nCS = EXP12, - //MPS2 shield 1 SPI - SHIELD_1_SPI_SCK = 331, - SHIELD_1_SPI_MOSI = 332, - SHIELD_1_SPI_MISO = 333, - SHIELD_1_SPI_nCS = 334, + /* MPS2 shield 1 SPI */ + SHIELD_1_SPI_MOSI = EXP39, + SHIELD_1_SPI_MISO = EXP40, + SHIELD_1_SPI_SCK = EXP44, + SHIELD_1_SPI_nCS = EXP38, - //MPS2 shield ADC SPI - ADC_MOSI = 650, - ADC_MISO = 651, - ADC_SCLK = 652, - ADC_SSEL = 653, + /* MPS2 shield ADC SPI */ + ADC_MOSI = EXP18, + ADC_MISO = EXP17, + ADC_SCLK = EXP19, + ADC_SSEL = EXP16, - //MPS2 Uart - USBTX = 400, - USBRX = 401, - XB_TX = 402, - XB_RX = 403, - SH0_TX = 404, - SH0_RX = 405, - SH1_TX = 406, - SH1_RX = 407, - MCC_TX = 408, - MCC_RX = 409, + /* MPS2 UART */ + MCC_TX = 400, + MCC_RX = 401, + USBTX = 402, + USBRX = 403, + XB_TX = EXP24, + XB_RX = EXP23, + SH0_TX = EXP4, + SH0_RX = EXP0, + SH1_TX = EXP30, + SH1_RX = EXP26, - //MPS2 I2C touchscreen and audio - TSC_SDA = 500, - TSC_SCL = 501, - AUD_SDA = 502, - AUD_SCL = 503, + /* MPS2 I2C touchscreen and audio */ + TSC_SDA = 500, + TSC_SCL = 501, + AUD_SDA = 502, + AUD_SCL = 503, - //MPS2 I2C for shield - SHIELD_0_SDA = 504, - SHIELD_0_SCL = 505, - SHIELD_1_SDA = 506, - SHIELD_1_SCL = 507, + /* MPS2 I2C for shield */ + SHIELD_0_SDA = EXP15, + SHIELD_0_SCL = EXP5, + SHIELD_1_SDA = EXP41, + SHIELD_1_SCL = EXP31, - //MPS2 shield Analog pins - A0_0 = 600, - A0_1 = 601, - A0_2 = 602, - A0_3 = 603, - A0_4 = 604, - A0_5 = 605, - A1_0 = 606, - A1_1 = 607, - A1_2 = 608, - A1_3 = 609, - A1_4 = 610, - A1_5 = 611, - //MPS2 Shield Digital pins - D0_0 = EXP0, - D0_1 = EXP4, - D0_2 = EXP2, - D0_3 = EXP3, - D0_4 = EXP1, - D0_5 = EXP6, - D0_6 = EXP7, - D0_7 = EXP8, - D0_8 = EXP9, - D0_9 = EXP10, - D0_10 = EXP12, - D0_11 = EXP13, - D0_12 = EXP14, - D0_13 = EXP11, - D0_14 = EXP15, - D0_15 = EXP5, + /* MPS2 shield Analog pins */ + A0_0 = 600, + A0_1 = 601, + A0_2 = 602, + A0_3 = 603, + A0_4 = 604, + A0_5 = 605, + A1_0 = 606, + A1_1 = 607, + A1_2 = 608, + A1_3 = 609, + A1_4 = 610, + A1_5 = 611, + /* MPS2 Shield Digital pins */ + D0_0 = EXP0, + D0_1 = EXP4, + D0_2 = EXP2, + D0_3 = EXP3, + D0_4 = EXP1, + D0_5 = EXP6, + D0_6 = EXP7, + D0_7 = EXP8, + D0_8 = EXP9, + D0_9 = EXP10, + D0_10 = EXP12, + D0_11 = EXP13, + D0_12 = EXP14, + D0_13 = EXP11, + D0_14 = EXP15, + D0_15 = EXP5, - D1_0 = EXP26, - D1_1 = EXP30, - D1_2 = EXP28, - D1_3 = EXP29, - D1_4 = EXP27, - D1_5 = EXP32, - D1_6 = EXP33, - D1_7 = EXP34, - D1_8 = EXP35, - D1_9 = EXP36, - D1_10 = EXP38, - D1_11 = EXP39, - D1_12 = EXP40, - D1_13 = EXP44, - D1_14 = EXP41, - D1_15 = EXP31, + D1_0 = EXP26, + D1_1 = EXP30, + D1_2 = EXP28, + D1_3 = EXP29, + D1_4 = EXP27, + D1_5 = EXP32, + D1_6 = EXP33, + D1_7 = EXP34, + D1_8 = EXP35, + D1_9 = EXP36, + D1_10 = EXP38, + D1_11 = EXP39, + D1_12 = EXP40, + D1_13 = EXP44, + D1_14 = EXP41, + D1_15 = EXP31, - // Not connected - NC = (int)0xFFFFFFFF, + /* Not connected */ + NC = (int)0xFFFFFFFF, } PinName; +typedef enum { + ALTERNATE_FUNC = 0, /* The pin is used for alternative function */ + GPIO_FUNC = 1 /* The pin is used for GPIO function */ +} PinFunction; + typedef enum { PullUp = 2, PullDown = 1, diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/gpio_api.c b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/gpio_api.c index 64524dc326..11e4d44e1d 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/gpio_api.c +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/gpio_api.c @@ -18,15 +18,7 @@ #include "gpio_api.h" #include "pinmap.h" -#define GPIO_NUM 4 - -CMSDK_GPIO_TypeDef* GPIO_MAP[GPIO_NUM] = { - CMSDK_GPIO0, - CMSDK_GPIO1, - CMSDK_GPIO2, - CMSDK_GPIO3 -}; - +#define GPIO_PIN_POS_MASK 0x0F /* pin % 16 */ #define RESERVED_MISC_PIN 7 /* \brief Gets the FPGA MISC (Miscellaneous control) bit position for the given @@ -69,83 +61,96 @@ static uint8_t get_fpga_misc_pin_pos(PinName pin) uint32_t gpio_set(PinName pin) { - /* TODO */ - return 1; + uint8_t pin_position; + + if (pin >=EXP0 && pin <= EXP51) { + /* Set pin functinality as GPIO. pin_function asserts if pin == NC */ + pin_function(pin, GPIO_FUNC); + } else { + /* Check if pin is a MISC pin */ + pin_position = get_fpga_misc_pin_pos(pin); + if (pin_position != RESERVED_MISC_PIN) { + return (1 << pin_position); + } + } + + /* Return pin mask */ + return (1 << (pin & 0xFF)); } void gpio_init(gpio_t *obj, PinName pin) { - uint8_t pin_position = 0; + uint8_t pin_position; if (pin == NC) { return; } - if(pin <= 15){ - pin_position = pin; + obj->pin = pin; + obj->pin_number = pin; + + if (pin <= EXP15) { obj->reg_data = &CMSDK_GPIO0->DATAOUT; obj->reg_in = &CMSDK_GPIO0->DATA; obj->reg_dir = &CMSDK_GPIO0->OUTENABLESET; obj->reg_dirclr = &CMSDK_GPIO0->OUTENABLECLR; - } else if (pin >= 16 && pin <= 31) { - pin_position = (pin - 16); + /* Set pin function as a GPIO */ + pin_function(pin, GPIO_FUNC); + pin_position = pin; + } else if (pin >= EXP16 && pin <= EXP31) { obj->reg_data = &CMSDK_GPIO1->DATAOUT; obj->reg_in = &CMSDK_GPIO1->DATA; obj->reg_dir = &CMSDK_GPIO1->OUTENABLESET; obj->reg_dirclr = &CMSDK_GPIO1->OUTENABLECLR; - } else if (pin >= 32 && pin <= 47) { - pin_position = (pin - 32); + /* Set pin function as a GPIO */ + pin_function(pin, GPIO_FUNC); + pin_position = (pin & GPIO_PIN_POS_MASK); + } else if (pin >= EXP32 && pin <= EXP47) { obj->reg_data = &CMSDK_GPIO2->DATAOUT; obj->reg_in = &CMSDK_GPIO2->DATA; obj->reg_dir = &CMSDK_GPIO2->OUTENABLESET; obj->reg_dirclr = &CMSDK_GPIO2->OUTENABLECLR; - } else if (pin >= 48 && pin <= 51) { - pin_position = (pin - 48 ); + /* Set pin function as a GPIO */ + pin_function(pin, GPIO_FUNC); + pin_position = (pin & GPIO_PIN_POS_MASK); + } else if (pin >= EXP48 && pin <= EXP51) { obj->reg_data = &CMSDK_GPIO3->DATAOUT; obj->reg_in = &CMSDK_GPIO3->DATA; obj->reg_dir = &CMSDK_GPIO3->OUTENABLESET; obj->reg_dirclr = &CMSDK_GPIO3->OUTENABLECLR; + /* Set pin function as a GPIO */ + pin_function(pin, GPIO_FUNC); + pin_position = (pin & GPIO_PIN_POS_MASK); } else if (pin == 100 || pin == 101) { /* User LEDs */ - pin_position = (pin - 100); + pin_position = (pin - 100); obj->reg_data = &MPS2_FPGAIO->LED; obj->reg_in = &MPS2_FPGAIO->LED; obj->reg_dir = NULL; obj->reg_dirclr = NULL; } else if (pin == 110 || pin == 111) { /* User buttons */ - pin_position = pin-110; + pin_position = (pin - 110); obj->reg_data = &MPS2_FPGAIO->BUTTON; obj->reg_in = &MPS2_FPGAIO->BUTTON; obj->reg_dir = NULL; obj->reg_dirclr = NULL; } else if (pin >= 200 && pin <= 207) { /* MCC LEDs */ - pin_position = pin-200; + pin_position = (pin - 200); obj->reg_data = &MPS2_SCC->LEDS; obj->reg_in = &MPS2_SCC->LEDS; obj->reg_dir = NULL; obj->reg_dirclr = NULL; } else if (pin >= 210 && pin <= 217) { /* MCC switches */ - pin_position = (pin - 210); + pin_position = (pin - 210); obj->reg_in = &MPS2_SCC->SWITCHES; obj->reg_data = NULL; obj->reg_dir = NULL; obj->reg_dirclr = NULL; - } else if (pin == SHIELD_0_SPI_nCS) { - pin_position = 8; - GPIO_MAP[CMSDK_GPIO_SH0_CS_SPI_GPIO_NUM]->ALTFUNCSET |= - (1 << CMSDK_GPIO_ALTFUNC_SH0_CS_SPI_SET); - } else if (pin == SHIELD_1_SPI_nCS) { - pin_position = 9; - GPIO_MAP[CMSDK_GPIO_SH1_CS_SPI_GPIO_NUM]->ALTFUNCSET |= - (1 << CMSDK_GPIO_ALTFUNC_SH1_CS_SPI_SET); - } else if (pin == ADC_SSEL) { - pin_position = 7; - GPIO_MAP[CMSDK_GPIO_ADC_CS_SPI_GPIO_NUM]->ALTFUNCSET |= - (1 << CMSDK_GPIO_ALTFUNC_ADC_CS_SPI_SET); } else { + /* Check if pin is a MISC pin */ pin_position = get_fpga_misc_pin_pos(pin); if (pin_position != RESERVED_MISC_PIN) { obj->reg_data = &MPS2_FPGAIO->MISC; @@ -154,9 +159,8 @@ void gpio_init(gpio_t *obj, PinName pin) } } - obj->pin = pin; - obj->mask = (0x1 << pin_position); - obj->pin_number = pin; + /* Set pin mask */ + obj->mask = (1 << pin_position); } void gpio_mode(gpio_t *obj, PinMode mode) diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/pinmap.c b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/pinmap.c index 136a71e96a..bb752f16be 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/pinmap.c +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/pinmap.c @@ -17,12 +17,34 @@ #include "pinmap.h" #include "mbed_error.h" +#define GET_GPIO_PIN_POS(pin) (pin & 0x0F) /* pin % 16 */ +#define GET_GPIO_MAP_NUM(pin) (pin >> 4) /* pin / 16 */ +#define GPIO_NUM 4 + +static CMSDK_GPIO_TypeDef* GPIO_MAP[GPIO_NUM] = { + CMSDK_GPIO0, + CMSDK_GPIO1, + CMSDK_GPIO2, + CMSDK_GPIO3 +}; void pin_function(PinName pin, int function) { + CMSDK_GPIO_TypeDef* p_gpio_map = 0; + MBED_ASSERT(pin != (PinName)NC); - /* TODO */ + if (pin >= EXP0 && pin <= EXP51) { + if (function == ALTERNATE_FUNC) { + p_gpio_map = GPIO_MAP[GET_GPIO_MAP_NUM(pin)]; + p_gpio_map->ALTFUNCSET = (1 << GET_GPIO_PIN_POS(pin)); + } else if(function == GPIO_FUNC) { + p_gpio_map = GPIO_MAP[GET_GPIO_MAP_NUM(pin)]; + p_gpio_map->ALTFUNCCLR = (1 << GET_GPIO_PIN_POS(pin)); + } else { + error("Invalid pin_function value %d", function); + } + } } void pin_mode(PinName pin, PinMode mode) diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/serial_api.c b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/serial_api.c index 9c6494a145..828d162a11 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/serial_api.c +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/serial_api.c @@ -32,25 +32,23 @@ static const PinMap PinMap_UART_TX[] = { {MCC_TX , UART_0, 0}, {USBTX , UART_1, 0}, - {XB_TX , UART_2, 0}, - {SH0_TX , UART_3, 0}, - {SH1_TX , UART_4, 0}, + {SH0_TX , UART_2, ALTERNATE_FUNC}, + {SH1_TX , UART_3, ALTERNATE_FUNC}, + {XB_TX , UART_4, ALTERNATE_FUNC}, {NC , NC , 0} }; static const PinMap PinMap_UART_RX[] = { {MCC_RX , UART_0, 0}, {USBRX , UART_1, 0}, - {XB_RX , UART_2, 0}, - {SH0_RX , UART_3, 0}, - {SH1_RX , UART_4, 0}, + {SH0_RX , UART_2, ALTERNATE_FUNC}, + {SH1_RX , UART_3, ALTERNATE_FUNC}, + {XB_RX , UART_4, ALTERNATE_FUNC}, {NC , NC , 0} }; #define UART_NUM 5 -extern CMSDK_GPIO_TypeDef* GPIO_MAP[]; - static uart_irq_handler irq_handler; int stdio_uart_inited = 0; @@ -66,6 +64,8 @@ static struct serial_global_data_s uart_data[UART_NUM]; void serial_init(serial_t *obj, PinName tx, PinName rx) { + uint32_t uart_ctrl = 0; + /* Determine the UART to use */ UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX); UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX); @@ -78,97 +78,48 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) obj->uart = (CMSDK_UART_TypeDef *)uart; + if (tx != NC) { + uart_ctrl = 0x01; /* TX enable */ + } + if (rx != NC) { + uart_ctrl |= 0x02; /* RX enable */ + } + switch (uart) { case UART_0: - /* Disable UART when changing configuration */ - CMSDK_UART0->CTRL = 0; - if((int)tx != NC) { - CMSDK_UART0->CTRL |= 0x01; /* TX enable */ - } - if((int)rx != NC) { - CMSDK_UART0->CTRL |= 0x02; /* RX enable */ - } + CMSDK_UART0->CTRL = uart_ctrl; + obj->index = 0; break; case UART_1: - /* Disable UART when changing configuration */ - CMSDK_UART1->CTRL = 0; - if((int)tx != NC) { - CMSDK_UART1->CTRL |= 0x01; /* TX enable */ - } - if((int)rx != NC) { - CMSDK_UART1->CTRL |= 0x02; /* RX enable */ - } + CMSDK_UART1->CTRL = uart_ctrl; + obj->index = 1; break; case UART_2: - /* Disable UART when changing configuration */ - CMSDK_UART2->CTRL = 0x00; - if ((int)tx != NC) { - CMSDK_UART2->CTRL = 0x1; /* TX enable */ - GPIO_MAP[CMSDK_GPIO_SH0_UART2_TX_GPIO_NUM]->ALTFUNCSET |= - (1<CTRL |= 0x2; /* RX enable */ - GPIO_MAP[CMSDK_GPIO_SH0_UART2_RX_GPIO_NUM]->ALTFUNCSET |= - (1<CTRL = 0; + obj->index = 2; + pin_function(tx, ALTERNATE_FUNC); + pin_function(rx, ALTERNATE_FUNC); + CMSDK_UART2->CTRL = uart_ctrl; break; case UART_3: - /* Disable UART when changing configuration */ CMSDK_UART3->CTRL = 0; - if ((int)tx != NC) { - CMSDK_UART3->CTRL = 0x1; /* TX enable */ - GPIO_MAP[CMSDK_GPIO_SH1_UART3_TX_GPIO_NUM]->ALTFUNCSET |= - (1<CTRL |= 0x2; /* RX enable */ - GPIO_MAP[CMSDK_GPIO_SH1_UART3_RX_GPIO_NUM]->ALTFUNCSET |= - (1<index = 3; + pin_function(tx, ALTERNATE_FUNC); + pin_function(rx, ALTERNATE_FUNC); + CMSDK_UART3->CTRL = uart_ctrl; break; case UART_4: - /* Disable UART when changing configuration */ - CMSDK_UART4->CTRL = 0x00; - if ((int)uart_tx != NC) { - CMSDK_UART4->CTRL |= 0x01; /* TX enable */ - GPIO_MAP[CMSDK_GPIO_UART4_TX_GPIO_NUM]->ALTFUNCSET |= - (1<CTRL |= 0x02; /* RX enable */ - GPIO_MAP[CMSDK_GPIO_UART4_RX_GPIO_NUM]->ALTFUNCSET |= - (1<CTRL = 0; + obj->index = 4; + pin_function(tx, ALTERNATE_FUNC); + pin_function(rx, ALTERNATE_FUNC); + CMSDK_UART4->CTRL = uart_ctrl; break; } /* Set default baud rate and format */ serial_baud(obj, 9600); - /* Pinout the chosen uart */ - pinmap_pinout(tx, PinMap_UART_TX); - pinmap_pinout(rx, PinMap_UART_RX); - - switch (uart) { - case UART_0: - obj->index = 0; - break; - case UART_1: - obj->index = 1; - break; - case UART_2: - obj->index = 2; - break; - case UART_3: - obj->index = 3; - break; - case UART_4: - obj->index = 4; - break; - } - /* * The CMSDK APB UART doesn't have support for flow control. * Ref. DDI0479C_cortex_m_system_design_kit_r1p0_trm.pdf @@ -180,6 +131,9 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) stdio_uart_inited = 1; memcpy(&stdio_uart, obj, sizeof(serial_t)); } + + /* Clear UART */ + serial_clear(obj); } void serial_free(serial_t *obj) diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/spi_api.c b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/spi_api.c index f69419a409..b42079e3a8 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/spi_api.c +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/spi_api.c @@ -29,49 +29,46 @@ #define SPI_PL022_SSPCR0_SCR_MSK (0xFFul<spi = (MPS2_SSP_TypeDef*)pinmap_merge(spi_data, spi_cntl); if ((int)obj->spi == NC) { error("SPI pinout mapping failed"); - return; } /* Enable power and clocking */ switch ((int)obj->spi) { - case (int)SPI_0: + case SPI_0: obj->spi->CR1 = 0; obj->spi->CR0 = SSP_CR0_SCR_DFLT | SSP_CR0_FRF_MOT | SSP_CR0_DSS_8; obj->spi->CPSR = SSP_CPSR_DFLT; @@ -97,7 +93,7 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel obj->spi->CR1 = SSP_CR1_SSE_Msk; obj->spi->ICR = 0x3; break; - case (int)SPI_1: /* Configure SSP used for LCD */ + case SPI_1: /* Configure SSP used for LCD */ obj->spi->CR1 = 0; /* Synchronous serial port disable */ obj->spi->DMACR = 0; /* Disable FIFO DMA */ obj->spi->IMSC = 0; /* Mask all FIFO/IRQ interrupts */ @@ -112,7 +108,9 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel obj->spi->CR1 = ((1ul << 1) | /* Synchronous serial port enable */ (0ul << 2) ); /* Device configured as master */ break; - case (int)SPI_2: + case SPI_2: /* Shield ADC SPI */ + case SPI_3: /* Shield 0 SPI */ + case SPI_4: /* Shield 1 SPI */ obj->spi->CR1 = 0; obj->spi->CR0 = SSP_CR0_SCR_DFLT | SSP_CR0_FRF_MOT | SSP_CR0_DSS_8; obj->spi->CPSR = SSP_CPSR_DFLT; @@ -120,79 +118,19 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel obj->spi->DMACR = 0; obj->spi->CR1 = SSP_CR1_SSE_Msk; obj->spi->ICR = 0x3; - break; - case (int)SPI_3: - obj->spi->CR1 = 0; - obj->spi->CR0 = SSP_CR0_SCR_DFLT | SSP_CR0_FRF_MOT | SSP_CR0_DSS_8; - obj->spi->CPSR = SSP_CPSR_DFLT; - obj->spi->IMSC = 0x8; - obj->spi->DMACR = 0; - obj->spi->CR1 = SSP_CR1_SSE_Msk; - obj->spi->ICR = 0x3; - break; - case (int)SPI_4: - obj->spi->CR1 = 0; - obj->spi->CR0 = SSP_CR0_SCR_DFLT | SSP_CR0_FRF_MOT | SSP_CR0_DSS_8; - obj->spi->CPSR = SSP_CPSR_DFLT; - obj->spi->IMSC = 0x8; - obj->spi->DMACR = 0; - obj->spi->CR1 = SSP_CR1_SSE_Msk; - obj->spi->ICR = 0x3; - break; - } - - if (mosi != NC) { - altfunction[0] = 1; - } else { - altfunction[0] = 0; - } - if (miso != NC) { - altfunction[1] = 1; - } else { - altfunction[1] = 0; - } - if (sclk != NC) { - altfunction[2] = 1; - } else { - altfunction[2] = 0; - } - if (ssel != NC) { - altfunction[3] = 1; - } else { - altfunction[3] = 0; - } - - /* Enable alt function */ - switch ((int)obj->spi) { - case (int)SPI_2: /* Shield ADC SPI */ - GPIO_MAP[CMSDK_GPIO_ADC_MOSI_SPI_GPIO_NUM]->ALTFUNCSET |= - (altfunction[0]<ALTFUNCSET |= - (altfunction[1]<ALTFUNCSET |= - (altfunction[2]<ALTFUNCSET |= - (altfunction[3]<ALTFUNCSET |= - (altfunction[0]<ALTFUNCSET |= - (altfunction[1]<ALTFUNCSET |= - (altfunction[2]<ALTFUNCSET |= - (altfunction[3]<ALTFUNCSET |= - (altfunction[0]<ALTFUNCSET |= - (altfunction[1]<ALTFUNCSET |= - (altfunction[2]<ALTFUNCSET |= - (altfunction[3]<spi->CR1; tmp &= ~(0xD); tmp |= 0 << 0 /* LBM - loop back mode - off */ - | ((slave) ? 1 : 0) << 2 /* MS - master slave mode, 1 = slave */ + | ((slave) ? 1 : 0) << 2 /* MS - master slave mode, 1 = slave */ | 0 << 3; /* SOD - slave output disable - na */ obj->spi->CR1 = tmp; @@ -260,12 +190,13 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) void spi_frequency(spi_t *obj, int hz) { uint32_t clkps_dvsr, scr; + uint32_t sys_clk = SystemCoreClock; for(clkps_dvsr = SPI_PL022_MIN_SSPCPSR_VALUE; clkps_dvsr <= SPI_PL022_MAX_SSPCPSR_VALUE; clkps_dvsr += 2) { /* Calculate clock rate based on the new clock prescale divisor */ - scr = (SystemCoreClock / (clkps_dvsr * hz)) - 1; + scr = (sys_clk / (clkps_dvsr * hz)) - 1; /* Checks if it can be supported by the divider */ if (scr <= SPI_PL022_MAX_SRC_VALUE) { @@ -278,7 +209,7 @@ void spi_frequency(spi_t *obj, int hz) } } - error("Couldn't setup requested SPI frequency"); + error("Couldn't setup requested SPI frequency %dHz", hz); } static inline int ssp_disable(spi_t *obj) From 985a2bb01d9b0f27e45b82020877c324b95c4066 Mon Sep 17 00:00:00 2001 From: Marc Moreno Berengue Date: Wed, 14 Jun 2017 10:23:14 +0100 Subject: [PATCH 2/5] Add I2C driver for CM3DS MPS2 target This patch adds the I2C driver for CM3DS MPS2 target. Signed-off-by: Marc Moreno --- .../TARGET_CM3DS_MPS2/device/SMM_MPS2.h | 8 +- .../TARGET_CM3DS_MPS2/i2c_api.c | 273 ++++++++++++++++++ .../TARGET_CM3DS_MPS2/objects.h | 1 + targets/targets.json | 2 +- 4 files changed, 277 insertions(+), 7 deletions(-) create mode 100644 targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/i2c_api.c diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/SMM_MPS2.h b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/SMM_MPS2.h index 03cba236b2..92709f61b4 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/SMM_MPS2.h +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/SMM_MPS2.h @@ -314,10 +314,6 @@ typedef struct __O uint32_t CONTROLC; // Offset: 0x004 CONTROL Clear Register ( /W) } MPS2_I2C_TypeDef; -#define SDA 1 << 1 -#define SCL 1 << 0 - - /******************************************************************************/ /* Audio I2S Peripheral declaration */ /******************************************************************************/ @@ -560,8 +556,8 @@ __IO uint32_t E2P_DATA; // EEPROM Data (offset 0xB4) #define MPS2_SSP3_BASE (0x40026000ul) /* shield 0 SSP Base Address */ #define MPS2_SSP4_BASE (0x40027000ul) /* shield 1 SSP Base Address */ #define MPS2_FPGAIO_BASE (0x40028000ul) /* FPGAIO Base Address */ -#define MPS2_SHIELD0_I2C_BASE (0x40029000ul) /* Audio Interface I2C Base Address */ -#define MPS2_SHIELD1_I2C_BASE (0x4002A000ul) /* Audio Interface I2C Base Address */ +#define MPS2_SHIELD0_I2C_BASE (0x40029000ul) /* I2C shield 0 Base Address */ +#define MPS2_SHIELD1_I2C_BASE (0x4002A000ul) /* I2C shield 1 Base Address */ #define MPS2_SCC_BASE (0x4002F000ul) /* SCC Base Address */ #define SMSC9220_BASE (0x40200000ul) /* Ethernet SMSC9220 Base Address */ diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/i2c_api.c b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/i2c_api.c new file mode 100644 index 0000000000..1496610a5c --- /dev/null +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/i2c_api.c @@ -0,0 +1,273 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 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 "i2c_api.h" +#include "cmsis.h" +#include "mbed_error.h" +#include "mbed_wait_api.h" +#include "SMM_MPS2.h" +#include "pinmap.h" + +/* + * The ARM I2C SBCon IP (Two-wire serial bus interface) requires a + * bit banging programing model. + */ + +#if DEVICE_I2CSLAVE +#error "I2C slave is not supported in MPS2 CM3DS board" +#endif + +#define DEFAULT_I2C_SBCON_HZ 4000000U /* 4MHz */ +#define STOP_REQUIRED 1 +#define LAST_ACK_REQUIRED 1 +#define LAST_ACK_NOT_REQUIRED 0 +#define I2C_ACK_BIT 0x1 + +#define SDA (1 << 1) +#define SCL (1 << 0) +#define I2C_HIGH(p_i2c, pin) (p_i2c->CONTROLS = pin) +#define I2C_LOW(p_i2c, pin) (p_i2c->CONTROLC = pin) +#define I2C_GET(p_i2c, pin) ((p_i2c->CONTROL >> (pin-1)) & 0x01) + +static const PinMap PinMap_I2C_SDA[] = { + {TSC_SDA , I2C_0, 0}, + {AUD_SDA , I2C_1, 0}, + {SHIELD_0_SDA , I2C_2, ALTERNATE_FUNC}, + {SHIELD_1_SDA , I2C_3, ALTERNATE_FUNC}, + {NC , NC , 0} +}; + +static const PinMap PinMap_I2C_SCL[] = { + {TSC_SCL , I2C_0, 0}, + {AUD_SCL , I2C_1, 0}, + {SHIELD_0_SCL , I2C_2, ALTERNATE_FUNC}, + {SHIELD_1_SCL , I2C_3, ALTERNATE_FUNC}, + {NC , NC, 0} +}; + +/* + * \brief Transmits a data bit. + * + * \param[in] obj I2C object + * \param[in] bit Bit to transmit + */ +static void i2c_tx_bit(i2c_t *obj, uint8_t bit) +{ + if (bit != 0) { + I2C_HIGH(obj->i2c, SDA); + } else { + I2C_LOW(obj->i2c, SDA); + } + + wait_us(obj->freq_us); + + I2C_HIGH(obj->i2c, SCL); + wait_us(obj->freq_us); + + I2C_LOW(obj->i2c, SCL); + wait_us(obj->freq_us); +} + +/* + * \brief Reads a data bit + * + * \param[in] obj I2C object + * + * \returns Bit value received. + */ +static uint8_t i2c_rx_bit(i2c_t *obj) +{ + uint8_t bit; + + I2C_HIGH(obj->i2c, SDA); + wait_us(obj->freq_us); + + I2C_HIGH(obj->i2c, SCL); + wait_us(obj->freq_us); + + bit = I2C_GET(obj->i2c, SDA); + + I2C_LOW(obj->i2c, SCL); + wait_us(obj->freq_us); + + return bit; +} + +void i2c_init(i2c_t *obj, PinName sda, PinName scl) +{ + I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA); + I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL); + obj->i2c = (MPS2_I2C_TypeDef *)pinmap_merge(i2c_sda, i2c_scl); + + if ((int)obj->i2c == NC) { + error("I2C pin mapping failed"); + } + + switch ((int)obj->i2c) { + case I2C_2: + case I2C_3: + /* Enables alt-function to use I2C SCL and SDA signals */ + pin_function(sda, ALTERNATE_FUNC); + pin_function(scl, ALTERNATE_FUNC); + break; + default: + break; + } + + /* Sets default I2C frequency in microseconds */ + obj->freq_us = (SystemCoreClock / DEFAULT_I2C_SBCON_HZ); +} + +void i2c_frequency(i2c_t *obj, int hz) +{ + if ((hz <= 0) || ((unsigned int)hz > SystemCoreClock)) { + error("Couldn't setup requested I2C frequency %dHz", hz); + } + + obj->freq_us = (SystemCoreClock / hz); +} + +int i2c_start(i2c_t *obj) +{ + I2C_HIGH(obj->i2c, (SCL | SDA)); + wait_us(obj->freq_us); + + I2C_LOW(obj->i2c, SDA); + wait_us(obj->freq_us); + + I2C_LOW(obj->i2c, SCL); + wait_us(obj->freq_us); + + return 0; +} + +int i2c_stop(i2c_t *obj) +{ + I2C_LOW(obj->i2c, SDA); + wait_us(obj->freq_us); + + I2C_HIGH(obj->i2c, SCL); + wait_us(obj->freq_us); + + I2C_HIGH(obj->i2c, SDA); + wait_us(obj->freq_us); + + return 0; +} + +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) +{ + int32_t nbr_bytes_read = 0; + + if (data == 0 || length == 0) { + error("Invalid i2c_read input data"); + } + + i2c_start(obj); + + i2c_byte_write(obj, (uint8_t)(address | 0x1)); + + while(nbr_bytes_read < (length - 1)) { + data[nbr_bytes_read++] = i2c_byte_read(obj, LAST_ACK_NOT_REQUIRED); + } + + data[nbr_bytes_read++] = i2c_byte_read(obj, LAST_ACK_REQUIRED); + + if (stop == STOP_REQUIRED) { + i2c_stop(obj); + } + + return nbr_bytes_read; +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) +{ + int32_t nbr_bytes_write; + + if (data == 0) { + error("Invalid i2c_write input data"); + } + + i2c_start(obj); + + i2c_byte_write(obj, (uint8_t)address); + + for (nbr_bytes_write = 0; nbr_bytes_write < length; nbr_bytes_write++) { + i2c_byte_write(obj, data[nbr_bytes_write]); + } + + if (stop == STOP_REQUIRED) { + i2c_stop(obj); + } + + return nbr_bytes_write; +} + +void i2c_reset(i2c_t *obj) +{ + uint32_t iter; + + /* + * The reset sequence is: + * - SDA line low + * - 9 clock pulses + * - SDA line high + */ + I2C_LOW(obj->i2c, SDA); + wait_us(obj->freq_us); + + for(iter=0; iter < 9; iter++) { + I2C_LOW(obj->i2c, SCL); + wait_us(obj->freq_us); + I2C_HIGH(obj->i2c, SCL); + wait_us(obj->freq_us); + } + + I2C_HIGH(obj->i2c, SDA); + wait_us(obj->freq_us); +} + +int i2c_byte_read(i2c_t *obj, int last) +{ + uint8_t nbr_bits; + uint8_t data = 0; + + data = i2c_rx_bit(obj); + for (nbr_bits = 1; nbr_bits < 8; nbr_bits++) { + data <<= 1; + data |= i2c_rx_bit(obj); + } + + i2c_tx_bit(obj, last); + + return data; +} + +int i2c_byte_write(i2c_t *obj, int data) +{ + uint8_t nbr_bits; + uint8_t ack; + + for(nbr_bits=0; nbr_bits < 7; nbr_bits++) { + i2c_tx_bit(obj, data & 0x80); + data <<= 1; + } + + i2c_tx_bit(obj, data & 0x80); + + ack = i2c_rx_bit(obj); + + return ack; +} diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/objects.h b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/objects.h index a9020b9066..d5fea381e3 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/objects.h +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/objects.h @@ -45,6 +45,7 @@ struct serial_s { struct i2c_s { MPS2_I2C_TypeDef *i2c; + uint32_t freq_us; /* Stores I2C frequency in microseconds */ }; struct tsc_s { diff --git a/targets/targets.json b/targets/targets.json index 165ac9f6cf..c97b9fd08c 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -1950,7 +1950,7 @@ "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], "extra_labels": ["ARM_SSG", "CM3DS_MPS2"], "macros": ["CMSDK_CM3DS"], - "device_has": ["ETHERNET","INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "SERIAL", "SPI", "RTC"], + "device_has": ["ETHERNET", "I2C", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "SERIAL", "SPI", "RTC"], "release_versions": ["2", "5"] }, "ARM_BEETLE_SOC": { From fabfc85d31069fce9c1280ba3fa75d215ce555d9 Mon Sep 17 00:00:00 2001 From: Marc Moreno Berengue Date: Wed, 14 Jun 2017 10:25:13 +0100 Subject: [PATCH 3/5] Add analogin driver for CM3DS MPS2 target This patch adds analogin driver for CM3DS MPS2 target. Signed-off-by: Hugues de Valon --- .../TARGET_CM3DS_MPS2/analogin_api.c | 153 ++++++++++++++++++ .../TARGET_CM3DS_MPS2/objects.h | 6 +- targets/targets.json | 2 +- 3 files changed, 155 insertions(+), 6 deletions(-) create mode 100644 targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/analogin_api.c diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/analogin_api.c b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/analogin_api.c new file mode 100644 index 0000000000..09028abdb1 --- /dev/null +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/analogin_api.c @@ -0,0 +1,153 @@ +/* mbed Microcontroller Library + * Copyright (c) 2017 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. + */ + +/* + * This HAL implementation uses the AD7490 analog-to-digital converter + * available on the MPS2 Adapter for Arduino shields. + */ + +#include "analogin_api.h" +#include "gpio_api.h" +#include "spi_api.h" +#include "mbed_error.h" +#include "mbed_wait_api.h" +#include "pinmap.h" + +/* + * There is only one AD7490 controller to read the analog pins in both shields. + * The AD7490 documentation (AD7490.pdf, page 12) tells us the right control + * register to send. + */ + +/* Output conversion is straight binary */ +#define CODING (1 << 0) +/* Analog input range from 0 to REF_IN volts */ +#define RANGE (1 << 1) +/* DOUT line state, weakly driven or three-state */ +#define WEAK_TRI (1 << 2) +/* Access to the shadow register */ +#define SHADOW (1 << 3) +/* Normal operation power mode */ +#define PM0 (1 << 4) +/* Normal operation power mode */ +#define PM1 (1 << 5) +/* Write control register */ +#define WRITE (1 << 11) +#define NORMAL_CONTROL_REGISTER (CODING | RANGE | PM0 | PM1 | WRITE) +/* The ADC will ignore the write of this control register */ +#define NO_WRITE_CONTROL_REGISTER 0x000 +/* Bit position of the channel number in the control register */ +#define CHANNEL_NUMBER_POSITION 6 +/* CS signal of the ADC needs to be put low during transfers */ +#define CS_LOW 0 +#define CS_HIGH 1 +/* The ADC expects a 16 bits word but only read the 12 most significant bits */ +#define USELESS_ADC_BITS 4 +/* The ADC result is on the 12 least significant bits */ +#define OUTPUT_DATA_MASK 0xFFF +/* The maximum value is the biggest value than can be coded on 12 bits */ +#define MAXIMUM_VALUE_12_BITS OUTPUT_DATA_MASK +#define FRAME_16_BITS 16 +#define NO_POLARITY_NO_PHASE 0 +#define MASTER_MODE 0 +/* Maximal SPI frequency as written in the ADC documentation */ +#define MAXIMAL_SPI_FREQUENCY_HZ 12000000 + +/* The value of the peripheral constant linked with one analog pins is the + * channel number of that pin on the ADC: + * A0_0 is channel 0 + * ... + * A0_5 is channel 5 + * A1_0 is channel 6 + * ... + * A1_5 is channel 11 + */ +static const PinMap PinMap_ADC[] = { + {A0_0, ADC0_0, 0}, + {A0_1, ADC0_1, 0}, + {A0_2, ADC0_2, 0}, + {A0_3, ADC0_3, 0}, + {A0_4, ADC0_4, 0}, + {A0_5, ADC0_5, 0}, + {A1_0, ADC0_6, 0}, + {A1_1, ADC0_7, 0}, + {A1_2, ADC0_8, 0}, + {A1_3, ADC0_9, 0}, + {A1_4, ADC0_10, 0}, + {A1_5, ADC0_11, 0}, + {NC , NC, 0} +}; + +/* mbed OS gpio_t structure for the CS pin linked to the ADC */ +static gpio_t adc_cs; + +/* mbed OS spi_t structure to communicate with the ADC */ +static spi_t adc_spi; + +void analogin_init(analogin_t *obj, PinName pin) +{ + uint16_t control_register = NORMAL_CONTROL_REGISTER; + uint32_t channel_number = pinmap_peripheral(pin, PinMap_ADC); + + if (channel_number == (uint32_t)NC) { + error("pin %d is not connected to the ADC", pin); + } + + /* Add the channel number to the control register */ + control_register |= (channel_number << CHANNEL_NUMBER_POSITION); + /* Only the 12 first bits are taken into account */ + control_register <<= USELESS_ADC_BITS; + obj->ctrl_register = control_register; + + spi_init(&adc_spi, ADC_MOSI, ADC_MISO, ADC_SCLK, NC); + spi_format(&adc_spi, FRAME_16_BITS, NO_POLARITY_NO_PHASE, MASTER_MODE); + spi_frequency(&adc_spi, MAXIMAL_SPI_FREQUENCY_HZ); + + gpio_init_out(&adc_cs, ADC_SSEL); +} + +uint16_t analogin_read_u16(analogin_t *obj) +{ + uint16_t result; + + /* Request conversion */ + gpio_write(&adc_cs, CS_LOW); + /* Only write the control register, ignore the previous results */ + (void)spi_master_write(&adc_spi, obj->ctrl_register); + gpio_write(&adc_cs, CS_HIGH); + + /* + * According to the documentation, t_QUIET (50 ns) time needs to pass before + * accessing to the SPI bus again. We wait here 1 us as we can not wait a + * shorter time than that. + */ + wait_us(1); + + /* Read conversion result */ + gpio_write(&adc_cs, CS_LOW); + /* Only read the results without writing the control register */ + result = spi_master_write(&adc_spi, NO_WRITE_CONTROL_REGISTER); + gpio_write(&adc_cs, CS_HIGH); + + return (result & OUTPUT_DATA_MASK); +} + +float analogin_read(analogin_t *obj) +{ + uint16_t result = analogin_read_u16(obj); + + return (result * (1. / MAXIMUM_VALUE_12_BITS)); +} diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/objects.h b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/objects.h index d5fea381e3..f60746f463 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/objects.h +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/objects.h @@ -66,11 +66,7 @@ struct clcd_s { }; struct analogin_s { - ADCName adc; - MPS2_SSP_TypeDef *adc_spi; - PinName pin; - uint32_t pin_number; - __IO uint32_t address; + uint16_t ctrl_register; /* Control bits with the channel identifier */ }; #include "gpio_object.h" diff --git a/targets/targets.json b/targets/targets.json index c97b9fd08c..2a1a80003b 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -1950,7 +1950,7 @@ "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], "extra_labels": ["ARM_SSG", "CM3DS_MPS2"], "macros": ["CMSDK_CM3DS"], - "device_has": ["ETHERNET", "I2C", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "SERIAL", "SPI", "RTC"], + "device_has": ["ANALOGIN", "ETHERNET", "I2C", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "SERIAL", "SPI", "RTC"], "release_versions": ["2", "5"] }, "ARM_BEETLE_SOC": { From 8de4c5323f1300e05c876172e7cc87cbc3f54686 Mon Sep 17 00:00:00 2001 From: Marc Moreno Berengue Date: Thu, 15 Jun 2017 16:32:25 +0100 Subject: [PATCH 4/5] Update CMSDK_CM3DS.h This patch updates CMSDK_CM3DS.h to remove the DMA peripheral memory map and defines, as that peripheral is not present in the system. In addition, some define names where updated concerning rtc. RTC_api was updated accordingly. This patch also updates SMM_MPS2 to align defines and comments. Signed-off-by: Marc Moreno --- .../TARGET_CM3DS_MPS2/device/CMSDK_CM3DS.h | 171 ++++-------------- .../TARGET_CM3DS_MPS2/device/SMM_MPS2.h | 40 ++-- .../TARGET_CM3DS_MPS2/rtc_api.c | 4 +- 3 files changed, 57 insertions(+), 158 deletions(-) diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/CMSDK_CM3DS.h b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/CMSDK_CM3DS.h index 9cba839ea7..06031211e1 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/CMSDK_CM3DS.h +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/CMSDK_CM3DS.h @@ -93,8 +93,8 @@ typedef enum IRQn MPS2_SPI0_IRQn = 49, /* SPI Interrupt (spi header) */ MPS2_SPI1_IRQn = 50, /* SPI Interrupt (clcd) */ MPS2_SPI2_IRQn = 51, /* SPI Interrupt (spi 1 ADC replacement) */ - MPS2_SPI3_IRQn = 52, /* SPI Interrupt (spi 0 shield 0 replacement) */ - MPS2_SPI4_IRQn = 53, /* SPI Interrupt (shield 1) */ + MPS2_SPI3_IRQn = 52, /* SPI Interrupt (shield 0) */ + MPS2_SPI4_IRQn = 53, /* SPI Interrupt (shield 1) */ PORT4_ALL_IRQn = 54, /* GPIO Port 4 combined Interrupt */ PORT5_ALL_IRQn = 55, /* GPIO Port 5 combined Interrupt */ UART4_IRQn = 56 /* UART 4 RX and TX Combined Interrupt */ @@ -635,104 +635,7 @@ typedef struct #define CMSDK_SYSCON_RSTINFO_LOCKUPRESET_Pos 2 #define CMSDK_SYSCON_RSTINFO_LOCKUPRESET_Msk (0x00001ul << CMSDK_SYSCON_RSTINFO_LOCKUPRESET_Pos) /* CMSDK_SYSCON RSTINFO: LOCKUPRESET Mask */ - -/*------------- PL230 uDMA (PL230) --------------------------------------*/ -typedef struct -{ - __I uint32_t DMA_STATUS; /* Offset: 0x000 (R/W) DMA status Register */ - __O uint32_t DMA_CFG; /* Offset: 0x004 ( /W) DMA configuration Register */ - __IO uint32_t CTRL_BASE_PTR; /* Offset: 0x008 (R/W) Channel Control Data Base Pointer Register */ - __I uint32_t ALT_CTRL_BASE_PTR; /* Offset: 0x00C (R/ ) Channel Alternate Control Data Base Pointer Register */ - __I uint32_t DMA_WAITONREQ_STATUS; /* Offset: 0x010 (R/ ) Channel Wait On Request Status Register */ - __O uint32_t CHNL_SW_REQUEST; /* Offset: 0x014 ( /W) Channel Software Request Register */ - __IO uint32_t CHNL_USEBURST_SET; /* Offset: 0x018 (R/W) Channel UseBurst Set Register */ - __O uint32_t CHNL_USEBURST_CLR; /* Offset: 0x01C ( /W) Channel UseBurst Clear Register */ - __IO uint32_t CHNL_REQ_MASK_SET; /* Offset: 0x020 (R/W) Channel Request Mask Set Register */ - __O uint32_t CHNL_REQ_MASK_CLR; /* Offset: 0x024 ( /W) Channel Request Mask Clear Register */ - __IO uint32_t CHNL_ENABLE_SET; /* Offset: 0x028 (R/W) Channel Enable Set Register */ - __O uint32_t CHNL_ENABLE_CLR; /* Offset: 0x02C ( /W) Channel Enable Clear Register */ - __IO uint32_t CHNL_PRI_ALT_SET; /* Offset: 0x030 (R/W) Channel Primary-Alterante Set Register */ - __O uint32_t CHNL_PRI_ALT_CLR; /* Offset: 0x034 ( /W) Channel Primary-Alterante Clear Register */ - __IO uint32_t CHNL_PRIORITY_SET; /* Offset: 0x038 (R/W) Channel Priority Set Register */ - __O uint32_t CHNL_PRIORITY_CLR; /* Offset: 0x03C ( /W) Channel Priority Clear Register */ - uint32_t RESERVED0[3]; - __IO uint32_t ERR_CLR; /* Offset: 0x04C Bus Error Clear Register (R/W) */ - -} CMSDK_PL230_TypeDef; - -#define PL230_DMA_CHNL_BITS 0 - -#define CMSDK_PL230_DMA_STATUS_MSTREN_Pos 0 /* CMSDK_PL230 DMA STATUS: MSTREN Position */ -#define CMSDK_PL230_DMA_STATUS_MSTREN_Msk (0x00000001ul << CMSDK_PL230_DMA_STATUS_MSTREN_Pos) /* CMSDK_PL230 DMA STATUS: MSTREN Mask */ - -#define CMSDK_PL230_DMA_STATUS_STATE_Pos 0 /* CMSDK_PL230 DMA STATUS: STATE Position */ -#define CMSDK_PL230_DMA_STATUS_STATE_Msk (0x0000000Ful << CMSDK_PL230_DMA_STATUS_STATE_Pos) /* CMSDK_PL230 DMA STATUS: STATE Mask */ - -#define CMSDK_PL230_DMA_STATUS_CHNLS_MINUS1_Pos 0 /* CMSDK_PL230 DMA STATUS: CHNLS_MINUS1 Position */ -#define CMSDK_PL230_DMA_STATUS_CHNLS_MINUS1_Msk (0x0000001Ful << CMSDK_PL230_DMA_STATUS_CHNLS_MINUS1_Pos) /* CMSDK_PL230 DMA STATUS: CHNLS_MINUS1 Mask */ - -#define CMSDK_PL230_DMA_STATUS_TEST_STATUS_Pos 0 /* CMSDK_PL230 DMA STATUS: TEST_STATUS Position */ -#define CMSDK_PL230_DMA_STATUS_TEST_STATUS_Msk (0x00000001ul << CMSDK_PL230_DMA_STATUS_TEST_STATUS_Pos) /* CMSDK_PL230 DMA STATUS: TEST_STATUS Mask */ - -#define CMSDK_PL230_DMA_CFG_MSTREN_Pos 0 /* CMSDK_PL230 DMA CFG: MSTREN Position */ -#define CMSDK_PL230_DMA_CFG_MSTREN_Msk (0x00000001ul << CMSDK_PL230_DMA_CFG_MSTREN_Pos) /* CMSDK_PL230 DMA CFG: MSTREN Mask */ - -#define CMSDK_PL230_DMA_CFG_CPCCACHE_Pos 2 /* CMSDK_PL230 DMA CFG: CPCCACHE Position */ -#define CMSDK_PL230_DMA_CFG_CPCCACHE_Msk (0x00000001ul << CMSDK_PL230_DMA_CFG_CPCCACHE_Pos) /* CMSDK_PL230 DMA CFG: CPCCACHE Mask */ - -#define CMSDK_PL230_DMA_CFG_CPCBUF_Pos 1 /* CMSDK_PL230 DMA CFG: CPCBUF Position */ -#define CMSDK_PL230_DMA_CFG_CPCBUF_Msk (0x00000001ul << CMSDK_PL230_DMA_CFG_CPCBUF_Pos) /* CMSDK_PL230 DMA CFG: CPCBUF Mask */ - -#define CMSDK_PL230_DMA_CFG_CPCPRIV_Pos 0 /* CMSDK_PL230 DMA CFG: CPCPRIV Position */ -#define CMSDK_PL230_DMA_CFG_CPCPRIV_Msk (0x00000001ul << CMSDK_PL230_DMA_CFG_CPCPRIV_Pos) /* CMSDK_PL230 DMA CFG: CPCPRIV Mask */ - -#define CMSDK_PL230_CTRL_BASE_PTR_Pos PL230_DMA_CHNL_BITS + 5 /* CMSDK_PL230 STATUS: BASE_PTR Position */ -#define CMSDK_PL230_CTRL_BASE_PTR_Msk (0x0FFFFFFFul << CMSDK_PL230_CTRL_BASE_PTR_Pos) /* CMSDK_PL230 STATUS: BASE_PTR Mask */ - -#define CMSDK_PL230_ALT_CTRL_BASE_PTR_Pos 0 /* CMSDK_PL230 STATUS: MSTREN Position */ -#define CMSDK_PL230_ALT_CTRL_BASE_PTR_Msk (0xFFFFFFFFul << CMSDK_PL230_ALT_CTRL_BASE_PTR_Pos) /* CMSDK_PL230 STATUS: MSTREN Mask */ - -#define CMSDK_PL230_DMA_WAITONREQ_STATUS_Pos 0 /* CMSDK_PL230 DMA_WAITONREQ_STATUS: DMA_WAITONREQ_STATUS Position */ -#define CMSDK_PL230_DMA_WAITONREQ_STATUS_Msk (0xFFFFFFFFul << CMSDK_PL230_DMA_WAITONREQ_STATUS_Pos) /* CMSDK_PL230 DMA_WAITONREQ_STATUS: DMA_WAITONREQ_STATUS Mask */ - -#define CMSDK_PL230_CHNL_SW_REQUEST_Pos 0 /* CMSDK_PL230 CHNL_SW_REQUEST: CHNL_SW_REQUEST Position */ -#define CMSDK_PL230_CHNL_SW_REQUEST_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_SW_REQUEST_Pos) /* CMSDK_PL230 CHNL_SW_REQUEST: CHNL_SW_REQUEST Mask */ - -#define CMSDK_PL230_CHNL_USEBURST_SET_Pos 0 /* CMSDK_PL230 CHNL_USEBURST: SET Position */ -#define CMSDK_PL230_CHNL_USEBURST_SET_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_USEBURST_SET_Pos) /* CMSDK_PL230 CHNL_USEBURST: SET Mask */ - -#define CMSDK_PL230_CHNL_USEBURST_CLR_Pos 0 /* CMSDK_PL230 CHNL_USEBURST: CLR Position */ -#define CMSDK_PL230_CHNL_USEBURST_CLR_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_USEBURST_CLR_Pos) /* CMSDK_PL230 CHNL_USEBURST: CLR Mask */ - -#define CMSDK_PL230_CHNL_REQ_MASK_SET_Pos 0 /* CMSDK_PL230 CHNL_REQ_MASK: SET Position */ -#define CMSDK_PL230_CHNL_REQ_MASK_SET_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_REQ_MASK_SET_Pos) /* CMSDK_PL230 CHNL_REQ_MASK: SET Mask */ - -#define CMSDK_PL230_CHNL_REQ_MASK_CLR_Pos 0 /* CMSDK_PL230 CHNL_REQ_MASK: CLR Position */ -#define CMSDK_PL230_CHNL_REQ_MASK_CLR_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_REQ_MASK_CLR_Pos) /* CMSDK_PL230 CHNL_REQ_MASK: CLR Mask */ - -#define CMSDK_PL230_CHNL_ENABLE_SET_Pos 0 /* CMSDK_PL230 CHNL_ENABLE: SET Position */ -#define CMSDK_PL230_CHNL_ENABLE_SET_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_ENABLE_SET_Pos) /* CMSDK_PL230 CHNL_ENABLE: SET Mask */ - -#define CMSDK_PL230_CHNL_ENABLE_CLR_Pos 0 /* CMSDK_PL230 CHNL_ENABLE: CLR Position */ -#define CMSDK_PL230_CHNL_ENABLE_CLR_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_ENABLE_CLR_Pos) /* CMSDK_PL230 CHNL_ENABLE: CLR Mask */ - -#define CMSDK_PL230_CHNL_PRI_ALT_SET_Pos 0 /* CMSDK_PL230 CHNL_PRI_ALT: SET Position */ -#define CMSDK_PL230_CHNL_PRI_ALT_SET_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_PRI_ALT_SET_Pos) /* CMSDK_PL230 CHNL_PRI_ALT: SET Mask */ - -#define CMSDK_PL230_CHNL_PRI_ALT_CLR_Pos 0 /* CMSDK_PL230 CHNL_PRI_ALT: CLR Position */ -#define CMSDK_PL230_CHNL_PRI_ALT_CLR_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_PRI_ALT_CLR_Pos) /* CMSDK_PL230 CHNL_PRI_ALT: CLR Mask */ - -#define CMSDK_PL230_CHNL_PRIORITY_SET_Pos 0 /* CMSDK_PL230 CHNL_PRIORITY: SET Position */ -#define CMSDK_PL230_CHNL_PRIORITY_SET_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_PRIORITY_SET_Pos) /* CMSDK_PL230 CHNL_PRIORITY: SET Mask */ - -#define CMSDK_PL230_CHNL_PRIORITY_CLR_Pos 0 /* CMSDK_PL230 CHNL_PRIORITY: CLR Position */ -#define CMSDK_PL230_CHNL_PRIORITY_CLR_Msk (0xFFFFFFFFul << CMSDK_PL230_CHNL_PRIORITY_CLR_Pos) /* CMSDK_PL230 CHNL_PRIORITY: CLR Mask */ - -#define CMSDK_PL230_ERR_CLR_Pos 0 /* CMSDK_PL230 ERR: CLR Position */ -#define CMSDK_PL230_ERR_CLR_Msk (0x00000001ul << CMSDK_PL230_ERR_CLR_Pos) /* CMSDK_PL230 ERR: CLR Mask */ - - -/*------------------- Watchdog ----------------------------------------------*/ +/*------------------- WATCHDOG ----------------------------------------------*/ typedef struct { @@ -749,35 +652,35 @@ typedef struct __O uint32_t ITOP; /* Offset: 0xF04 ( /W) Watchdog Integration Test Output Set Register */ }CMSDK_WATCHDOG_TypeDef; -#define CMSDK_Watchdog_LOAD_Pos 0 /* CMSDK_Watchdog LOAD: LOAD Position */ -#define CMSDK_Watchdog_LOAD_Msk (0xFFFFFFFFul << CMSDK_Watchdog_LOAD_Pos) /* CMSDK_Watchdog LOAD: LOAD Mask */ +#define CMSDK_WATCHDOG_LOAD_Pos 0 /* CMSDK_WATCHDOG LOAD: LOAD Position */ +#define CMSDK_WATCHDOG_LOAD_Msk (0xFFFFFFFFul << CMSDK_WATCHDOG_LOAD_Pos) /* CMSDK_WATCHDOG LOAD: LOAD Mask */ -#define CMSDK_Watchdog_VALUE_Pos 0 /* CMSDK_Watchdog VALUE: VALUE Position */ -#define CMSDK_Watchdog_VALUE_Msk (0xFFFFFFFFul << CMSDK_Watchdog_VALUE_Pos) /* CMSDK_Watchdog VALUE: VALUE Mask */ +#define CMSDK_WATCHDOG_VALUE_Pos 0 /* CMSDK_WATCHDOG VALUE: VALUE Position */ +#define CMSDK_WATCHDOG_VALUE_Msk (0xFFFFFFFFul << CMSDK_WATCHDOG_VALUE_Pos) /* CMSDK_WATCHDOG VALUE: VALUE Mask */ -#define CMSDK_Watchdog_CTRL_RESEN_Pos 1 /* CMSDK_Watchdog CTRL_RESEN: Enable Reset Output Position */ -#define CMSDK_Watchdog_CTRL_RESEN_Msk (0x1ul << CMSDK_Watchdog_CTRL_RESEN_Pos) /* CMSDK_Watchdog CTRL_RESEN: Enable Reset Output Mask */ +#define CMSDK_WATCHDOG_CTRL_RESEN_Pos 1 /* CMSDK_WATCHDOG CTRL_RESEN: Enable Reset Output Position */ +#define CMSDK_WATCHDOG_CTRL_RESEN_Msk (0x1ul << CMSDK_WATCHDOG_CTRL_RESEN_Pos) /* CMSDK_WATCHDOG CTRL_RESEN: Enable Reset Output Mask */ -#define CMSDK_Watchdog_CTRL_INTEN_Pos 0 /* CMSDK_Watchdog CTRL_INTEN: Int Enable Position */ -#define CMSDK_Watchdog_CTRL_INTEN_Msk (0x1ul << CMSDK_Watchdog_CTRL_INTEN_Pos) /* CMSDK_Watchdog CTRL_INTEN: Int Enable Mask */ +#define CMSDK_WATCHDOG_CTRL_INTEN_Pos 0 /* CMSDK_WATCHDOG CTRL_INTEN: Int Enable Position */ +#define CMSDK_WATCHDOG_CTRL_INTEN_Msk (0x1ul << CMSDK_WATCHDOG_CTRL_INTEN_Pos) /* CMSDK_WATCHDOG CTRL_INTEN: Int Enable Mask */ -#define CMSDK_Watchdog_INTCLR_Pos 0 /* CMSDK_Watchdog INTCLR: Int Clear Position */ -#define CMSDK_Watchdog_INTCLR_Msk (0x1ul << CMSDK_Watchdog_INTCLR_Pos) /* CMSDK_Watchdog INTCLR: Int Clear Mask */ +#define CMSDK_WATCHDOG_INTCLR_Pos 0 /* CMSDK_WATCHDOG INTCLR: Int Clear Position */ +#define CMSDK_WATCHDOG_INTCLR_Msk (0x1ul << CMSDK_WATCHDOG_INTCLR_Pos) /* CMSDK_WATCHDOG INTCLR: Int Clear Mask */ -#define CMSDK_Watchdog_RAWINTSTAT_Pos 0 /* CMSDK_Watchdog RAWINTSTAT: Raw Int Status Position */ -#define CMSDK_Watchdog_RAWINTSTAT_Msk (0x1ul << CMSDK_Watchdog_RAWINTSTAT_Pos) /* CMSDK_Watchdog RAWINTSTAT: Raw Int Status Mask */ +#define CMSDK_WATCHDOG_RAWINTSTAT_Pos 0 /* CMSDK_WATCHDOG RAWINTSTAT: Raw Int Status Position */ +#define CMSDK_WATCHDOG_RAWINTSTAT_Msk (0x1ul << CMSDK_WATCHDOG_RAWINTSTAT_Pos) /* CMSDK_WATCHDOG RAWINTSTAT: Raw Int Status Mask */ -#define CMSDK_Watchdog_MASKINTSTAT_Pos 0 /* CMSDK_Watchdog MASKINTSTAT: Mask Int Status Position */ -#define CMSDK_Watchdog_MASKINTSTAT_Msk (0x1ul << CMSDK_Watchdog_MASKINTSTAT_Pos) /* CMSDK_Watchdog MASKINTSTAT: Mask Int Status Mask */ +#define CMSDK_WATCHDOG_MASKINTSTAT_Pos 0 /* CMSDK_WATCHDOG MASKINTSTAT: Mask Int Status Position */ +#define CMSDK_WATCHDOG_MASKINTSTAT_Msk (0x1ul << CMSDK_WATCHDOG_MASKINTSTAT_Pos) /* CMSDK_WATCHDOG MASKINTSTAT: Mask Int Status Mask */ -#define CMSDK_Watchdog_LOCK_Pos 0 /* CMSDK_Watchdog LOCK: LOCK Position */ -#define CMSDK_Watchdog_LOCK_Msk (0x1ul << CMSDK_Watchdog_LOCK_Pos) /* CMSDK_Watchdog LOCK: LOCK Mask */ +#define CMSDK_WATCHDOG_LOCK_Pos 0 /* CMSDK_WATCHDOG LOCK: LOCK Position */ +#define CMSDK_WATCHDOG_LOCK_Msk (0x1ul << CMSDK_WATCHDOG_LOCK_Pos) /* CMSDK_WATCHDOG LOCK: LOCK Mask */ -#define CMSDK_Watchdog_INTEGTESTEN_Pos 0 /* CMSDK_Watchdog INTEGTESTEN: Integration Test Enable Position */ -#define CMSDK_Watchdog_INTEGTESTEN_Msk (0x1ul << CMSDK_Watchdog_INTEGTESTEN_Pos) /* CMSDK_Watchdog INTEGTESTEN: Integration Test Enable Mask */ +#define CMSDK_WATCHDOG_INTEGTESTEN_Pos 0 /* CMSDK_WATCHDOG INTEGTESTEN: Integration Test Enable Position */ +#define CMSDK_WATCHDOG_INTEGTESTEN_Msk (0x1ul << CMSDK_WATCHDOG_INTEGTESTEN_Pos) /* CMSDK_WATCHDOG INTEGTESTEN: Integration Test Enable Mask */ -#define CMSDK_Watchdog_INTEGTESTOUTSET_Pos 1 /* CMSDK_Watchdog INTEGTESTOUTSET: Integration Test Output Set Position */ -#define CMSDK_Watchdog_INTEGTESTOUTSET_Msk (0x1ul << CMSDK_Watchdog_INTEGTESTOUTSET_Pos) /* CMSDK_Watchdog INTEGTESTOUTSET: Integration Test Output Set Mask */ +#define CMSDK_WATCHDOG_INTEGTESTOUTSET_Pos 1 /* CMSDK_WATCHDOG INTEGTESTOUTSET: Integration Test Output Set Position */ +#define CMSDK_WATCHDOG_INTEGTESTOUTSET_Msk (0x1ul << CMSDK_WATCHDOG_INTEGTESTOUTSET_Pos) /* CMSDK_WATCHDOG INTEGTESTOUTSET: Integration Test Output Set Mask */ /*------------------------- Real Time Clock(RTC) ----------------------------------------------*/ typedef struct @@ -792,8 +695,8 @@ typedef struct __O uint32_t RTCICR; /* 0x1C WO RTC Interrupt Clear Register */ } CMSDK_RTC_TypeDef; -#define CMSDK_RTC_Enable_Pos 0 /* CMSDK_RTC Enable: Real Time Clock Enable Position */ -#define CMSDK_RTC_Enable_Msk (0x1ul << CMSDK_RTC_Enable_Pos) /* CMSDK_RTC Enable: Real Time Clock Enable Mask */ +#define CMSDK_RTC_ENABLE_Pos 0 /* CMSDK_RTC Enable: Real Time Clock Enable Position */ +#define CMSDK_RTC_ENABLE_Msk (0x1ul << CMSDK_RTC_ENABLE_Pos) /* CMSDK_RTC Enable: Real Time Clock Enable Mask */ /* -------------------- End of section using anonymous unions ------------------- */ #if defined ( __CC_ARM ) @@ -810,9 +713,6 @@ typedef struct #warning Not supported compiler type #endif - - - /* ================================================================================ */ /* ================ Peripheral memory map ================ */ /* ================================================================================ */ @@ -855,21 +755,20 @@ typedef struct /* ================ Peripheral declaration ================ */ /* ================================================================================ */ -#define CMSDK_UART0 ((CMSDK_UART_TypeDef *) CMSDK_UART0_BASE ) -#define CMSDK_UART1 ((CMSDK_UART_TypeDef *) CMSDK_UART1_BASE ) -#define CMSDK_UART2 ((CMSDK_UART_TypeDef *) CMSDK_UART2_BASE ) -#define CMSDK_UART3 ((CMSDK_UART_TypeDef *) CMSDK_UART3_BASE ) -#define CMSDK_UART4 ((CMSDK_UART_TypeDef *) CMSDK_UART4_BASE ) -#define CMSDK_TIMER0 ((CMSDK_TIMER_TypeDef *) CMSDK_TIMER0_BASE ) -#define CMSDK_TIMER1 ((CMSDK_TIMER_TypeDef *) CMSDK_TIMER1_BASE ) +#define CMSDK_UART0 ((CMSDK_UART_TypeDef *) CMSDK_UART0_BASE ) +#define CMSDK_UART1 ((CMSDK_UART_TypeDef *) CMSDK_UART1_BASE ) +#define CMSDK_UART2 ((CMSDK_UART_TypeDef *) CMSDK_UART2_BASE ) +#define CMSDK_UART3 ((CMSDK_UART_TypeDef *) CMSDK_UART3_BASE ) +#define CMSDK_UART4 ((CMSDK_UART_TypeDef *) CMSDK_UART4_BASE ) +#define CMSDK_TIMER0 ((CMSDK_TIMER_TypeDef *) CMSDK_TIMER0_BASE ) +#define CMSDK_TIMER1 ((CMSDK_TIMER_TypeDef *) CMSDK_TIMER1_BASE ) #define CMSDK_DUALTIMER ((CMSDK_DUALTIMER_BOTH_TypeDef *) CMSDK_DUALTIMER_BASE ) #define CMSDK_DUALTIMER1 ((CMSDK_DUALTIMER_SINGLE_TypeDef *) CMSDK_DUALTIMER_1_BASE ) #define CMSDK_DUALTIMER2 ((CMSDK_DUALTIMER_SINGLE_TypeDef *) CMSDK_DUALTIMER_2_BASE ) #define CMSDK_RTC ((CMSDK_RTC_TypeDef *) CMSDK_RTC_BASE ) -#define CMSDK_WATCHDOG ((CMSDK_WATCHDOG_TypeDef *) CMSDK_WATCHDOG_BASE ) -#define CMSDK_DMA ((CMSDK_PL230_TypeDef *) CMSDK_PL230_BASE ) -#define CMSDK_GPIO0 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO0_BASE ) -#define CMSDK_GPIO1 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO1_BASE ) +#define CMSDK_WATCHDOG ((CMSDK_WATCHDOG_TypeDef *) CMSDK_WATCHDOG_BASE ) +#define CMSDK_GPIO0 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO0_BASE ) +#define CMSDK_GPIO1 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO1_BASE ) #define CMSDK_GPIO2 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO2_BASE ) #define CMSDK_GPIO3 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO3_BASE ) #define CMSDK_GPIO4 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO4_BASE ) diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/SMM_MPS2.h b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/SMM_MPS2.h index 92709f61b4..0920930a2d 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/SMM_MPS2.h +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/device/SMM_MPS2.h @@ -547,20 +547,20 @@ __IO uint32_t E2P_DATA; // EEPROM Data (offset 0xB4) /* Peripheral memory map */ /******************************************************************************/ -#define MPS2_SSP0_BASE (0x40020000ul) /* User SSP Base Address */ -#define MPS2_SSP1_BASE (0x40021000ul) /* CLCD SSP Base Address */ +#define MPS2_SSP0_BASE (0x40020000ul) /* User SSP Base Address */ +#define MPS2_SSP1_BASE (0x40021000ul) /* CLCD SSP Base Address */ #define MPS2_TSC_I2C_BASE (0x40022000ul) /* Touch Screen I2C Base Address */ #define MPS2_AAIC_I2C_BASE (0x40023000ul) /* Audio Interface I2C Base Address */ #define MPS2_AAIC_I2S_BASE (0x40024000ul) /* Audio Interface I2S Base Address */ -#define MPS2_SSP2_BASE (0x40025000ul) /* adc SSP Base Address */ -#define MPS2_SSP3_BASE (0x40026000ul) /* shield 0 SSP Base Address */ -#define MPS2_SSP4_BASE (0x40027000ul) /* shield 1 SSP Base Address */ +#define MPS2_SSP2_BASE (0x40025000ul) /* ADC SSP Base Address */ +#define MPS2_SSP3_BASE (0x40026000ul) /* Shield 0 SSP Base Address */ +#define MPS2_SSP4_BASE (0x40027000ul) /* Shield 1 SSP Base Address */ #define MPS2_FPGAIO_BASE (0x40028000ul) /* FPGAIO Base Address */ #define MPS2_SHIELD0_I2C_BASE (0x40029000ul) /* I2C shield 0 Base Address */ #define MPS2_SHIELD1_I2C_BASE (0x4002A000ul) /* I2C shield 1 Base Address */ -#define MPS2_SCC_BASE (0x4002F000ul) /* SCC Base Address */ +#define MPS2_SCC_BASE (0x4002F000ul) /* SCC Base Address */ -#define SMSC9220_BASE (0x40200000ul) /* Ethernet SMSC9220 Base Address */ +#define SMSC9220_BASE (0x40200000ul) /* Ethernet SMSC9220 Base Address */ #define MPS2_VGA_TEXT_BUFFER (0x41000000ul) /* VGA Text Buffer Address */ #define MPS2_VGA_BUFFER (0x41100000ul) /* VGA Buffer Base Address */ @@ -569,19 +569,19 @@ __IO uint32_t E2P_DATA; // EEPROM Data (offset 0xB4) /* Peripheral declaration */ /******************************************************************************/ -#define SMSC9220 ((SMSC9220_TypeDef *) SMSC9220_BASE ) -#define MPS2_TS_I2C ((MPS2_I2C_TypeDef *) MPS2_TSC_I2C_BASE ) -#define MPS2_AAIC_I2C ((MPS2_I2C_TypeDef *) MPS2_AAIC_I2C_BASE ) -#define MPS2_SHIELD0_I2C ((MPS2_I2C_TypeDef *) MPS2_SHIELD0_I2C_BASE ) -#define MPS2_SHIELD1_I2C ((MPS2_I2C_TypeDef *) MPS2_SHIELD1_I2C_BASE ) -#define MPS2_AAIC_I2S ((MPS2_I2S_TypeDef *) MPS2_AAIC_I2S_BASE ) -#define MPS2_FPGAIO ((MPS2_FPGAIO_TypeDef *) MPS2_FPGAIO_BASE ) -#define MPS2_SCC ((MPS2_SCC_TypeDef *) MPS2_SCC_BASE ) -#define MPS2_SSP0 ((MPS2_SSP_TypeDef *) MPS2_SSP0_BASE ) -#define MPS2_SSP1 ((MPS2_SSP_TypeDef *) MPS2_SSP1_BASE ) -#define MPS2_SSP2 ((MPS2_SSP_TypeDef *) MPS2_SSP2_BASE ) -#define MPS2_SSP3 ((MPS2_SSP_TypeDef *) MPS2_SSP3_BASE ) -#define MPS2_SSP4 ((MPS2_SSP_TypeDef *) MPS2_SSP4_BASE ) +#define SMSC9220 ((SMSC9220_TypeDef *) SMSC9220_BASE ) +#define MPS2_TS_I2C ((MPS2_I2C_TypeDef *) MPS2_TSC_I2C_BASE ) +#define MPS2_AAIC_I2C ((MPS2_I2C_TypeDef *) MPS2_AAIC_I2C_BASE ) +#define MPS2_SHIELD0_I2C ((MPS2_I2C_TypeDef *) MPS2_SHIELD0_I2C_BASE ) +#define MPS2_SHIELD1_I2C ((MPS2_I2C_TypeDef *) MPS2_SHIELD1_I2C_BASE ) +#define MPS2_AAIC_I2S ((MPS2_I2S_TypeDef *) MPS2_AAIC_I2S_BASE ) +#define MPS2_FPGAIO ((MPS2_FPGAIO_TypeDef *) MPS2_FPGAIO_BASE ) +#define MPS2_SCC ((MPS2_SCC_TypeDef *) MPS2_SCC_BASE ) +#define MPS2_SSP0 ((MPS2_SSP_TypeDef *) MPS2_SSP0_BASE ) +#define MPS2_SSP1 ((MPS2_SSP_TypeDef *) MPS2_SSP1_BASE ) +#define MPS2_SSP2 ((MPS2_SSP_TypeDef *) MPS2_SSP2_BASE ) +#define MPS2_SSP3 ((MPS2_SSP_TypeDef *) MPS2_SSP3_BASE ) +#define MPS2_SSP4 ((MPS2_SSP_TypeDef *) MPS2_SSP4_BASE ) /******************************************************************************/ /* General Function Definitions */ diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/rtc_api.c b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/rtc_api.c index 4f0a4d1c9a..2de348666a 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/rtc_api.c +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/rtc_api.c @@ -31,7 +31,7 @@ */ void rtc_init(void) { - CMSDK_RTC->RTCCR |= (1 << CMSDK_RTC_Enable_Pos); + CMSDK_RTC->RTCCR |= (1 << CMSDK_RTC_ENABLE_Pos); } /** @@ -51,7 +51,7 @@ void rtc_free(void) */ int rtc_isenabled(void) { - return (CMSDK_RTC->RTCCR & CMSDK_RTC_Enable_Msk); + return (CMSDK_RTC->RTCCR & CMSDK_RTC_ENABLE_Msk); } /** From 6b04bb364fe1749ba67e054946b4b31751bbe86b Mon Sep 17 00:00:00 2001 From: Marc Moreno Berengue Date: Thu, 15 Jun 2017 16:35:49 +0100 Subject: [PATCH 5/5] Update port api driver to add missing ports This patch updates port api driver to add missing ports. Signed-off-by: Marc Moreno --- .../TARGET_CM3DS_MPS2/PortNames.h | 4 +- .../TARGET_CM3DS_MPS2/port_api.c | 43 +++++++++++++------ 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/PortNames.h b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/PortNames.h index cfe07fd3d3..983190e499 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/PortNames.h +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/PortNames.h @@ -22,7 +22,9 @@ extern "C" { typedef enum { Port0 = 0, - Port1 = 1 + Port1, + Port2, + Port3, } PortName; #ifdef __cplusplus diff --git a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/port_api.c b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/port_api.c index 99414d28ac..61c4ca8d52 100644 --- a/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/port_api.c +++ b/targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/port_api.c @@ -17,26 +17,45 @@ #include "pinmap.h" #include "gpio_api.h" +#define MAX_GPIO_PINS 16 + PinName port_pin(PortName port, int pin_n) { + if (pin_n < 0 || pin_n > MAX_GPIO_PINS) { + error("Invalid GPIO pin number %d", pin_n); + } + return (PinName)((port << PORT_SHIFT) | pin_n); } void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { - obj->port = port; - obj->mask = mask; + uint32_t i; + CMSDK_GPIO_TypeDef *port_reg; - CMSDK_GPIO_TypeDef *port_reg = (CMSDK_GPIO_TypeDef *)(CMSDK_GPIO0_BASE - + ((int)port * 0x10)); + switch (port) { + case Port0: + port_reg = (CMSDK_GPIO_TypeDef *)(CMSDK_GPIO0_BASE); + break; + case Port1: + port_reg = (CMSDK_GPIO_TypeDef *)(CMSDK_GPIO1_BASE); + break; + case Port2: + port_reg = (CMSDK_GPIO_TypeDef *)(CMSDK_GPIO2_BASE); + break; + case Port3: + port_reg = (CMSDK_GPIO_TypeDef *)(CMSDK_GPIO3_BASE); + break; + } - obj->reg_in = &port_reg->DATAOUT; - obj->reg_dir = &port_reg->OUTENABLESET; + obj->port = port; + obj->mask = mask; + obj->reg_in = &port_reg->DATAOUT; + obj->reg_dir = &port_reg->OUTENABLESET; obj->reg_dirclr = &port_reg->OUTENABLECLR; - uint32_t i; - // The function is set per pin: reuse gpio logic - for (i=0; i<16; i++) { + /* The function is set per pin: reuse gpio logic */ + for (i=0; i < MAX_GPIO_PINS; i++) { if (obj->mask & (1<port, i)); } @@ -48,9 +67,9 @@ void port_init(port_t *obj, PortName port, int mask, PinDirection dir) void port_mode(port_t *obj, PinMode mode) { uint32_t i; - // The mode is set per pin: reuse pinmap logic - for (i=0; i<32; i++) { - if (obj->mask & (1<mask & (1 << i)) { pin_mode(port_pin(obj->port, i), mode); } }