Merge pull request #4557 from mmorenobarm/master

Enable I2C and Analogin drivers for CM3DS_MPS2 target
pull/4639/head
Jimmy Brisson 2017-06-26 10:28:08 -05:00 committed by GitHub
commit 17a88a80ef
14 changed files with 850 additions and 597 deletions

View File

@ -30,72 +30,70 @@ 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
/* User leds */
USERLED1 = 100,
USERLED2 = 101,
//user switches
/* User switches */
USERSW1 = 110,
USERSW2 = 111,
//mcc leds
/* MCC leds */
LED1 = 200,
LED2 = 201,
LED3 = 202,
@ -105,7 +103,7 @@ typedef enum {
LED7 = 206,
LED8 = 207,
//MCC Switches
/* MCC Switches */
SW1 = 210,
SW2 = 211,
SW3 = 212,
@ -115,13 +113,13 @@ typedef enum {
SW7 = 216,
SW8 = 217,
//MPS2 SPI header pins j21
/* MPS2 SPI header pins J21 */
SPI_MOSI = 300,
SPI_MISO = 301,
SPI_SCLK = 302,
SPI_SSEL = 303,
//MPS2 CLCD SPI
/* MPS2 CLCD SPI */
CLCD_MOSI = 304,
CLCD_MISO = 305,
CLCD_SCLK = 306,
@ -131,49 +129,49 @@ typedef enum {
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
/* 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
/* MPS2 shield Analog pins */
A0_0 = 600,
A0_1 = 601,
A0_2 = 602,
@ -186,7 +184,7 @@ typedef enum {
A1_3 = 609,
A1_4 = 610,
A1_5 = 611,
//MPS2 Shield Digital pins
/* MPS2 Shield Digital pins */
D0_0 = EXP0,
D0_1 = EXP4,
D0_2 = EXP2,
@ -221,10 +219,15 @@ typedef enum {
D1_14 = EXP41,
D1_15 = EXP31,
// Not connected
/* 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,

View File

@ -22,7 +22,9 @@ extern "C" {
typedef enum {
Port0 = 0,
Port1 = 1
Port1,
Port2,
Port3,
} PortName;
#ifdef __cplusplus

View File

@ -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));
}

View File

@ -93,7 +93,7 @@ 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_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 */
@ -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 ================ */
/* ================================================================================ */
@ -867,7 +767,6 @@ typedef struct
#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_GPIO2 ((CMSDK_GPIO_TypeDef *) CMSDK_GPIO2_BASE )

View File

@ -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 */
/******************************************************************************/
@ -556,12 +552,12 @@ __IO uint32_t E2P_DATA; // EEPROM Data (offset 0xB4)
#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) /* 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 */

View File

@ -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,42 +61,66 @@ 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);
@ -114,14 +130,14 @@ void gpio_init(gpio_t *obj, PinName pin)
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;
@ -133,19 +149,8 @@ void gpio_init(gpio_t *obj, PinName pin)
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)

View File

@ -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;
}

View File

@ -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 {
@ -65,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"

View File

@ -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)

View File

@ -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)
{
uint32_t i;
CMSDK_GPIO_TypeDef *port_reg;
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->port = port;
obj->mask = mask;
CMSDK_GPIO_TypeDef *port_reg = (CMSDK_GPIO_TypeDef *)(CMSDK_GPIO0_BASE
+ ((int)port * 0x10));
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<<i)) {
gpio_set(port_pin(obj->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<<i)) {
/* The mode is set per pin: reuse pinmap logic */
for (i=0; i < MAX_GPIO_PINS; i++) {
if (obj->mask & (1 << i)) {
pin_mode(port_pin(obj->port, i), mode);
}
}

View File

@ -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);
}
/**

View File

@ -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<<CMSDK_GPIO_ALTFUNC_SH0_UART2_TX_SET);
}
if ((int)rx != NC) {
CMSDK_UART2->CTRL |= 0x2; /* RX enable */
GPIO_MAP[CMSDK_GPIO_SH0_UART2_RX_GPIO_NUM]->ALTFUNCSET |=
(1<<CMSDK_GPIO_ALTFUNC_SH0_UART2_RX_SET);
}
CMSDK_UART2->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<<CMSDK_GPIO_ALTFUNC_SH1_UART3_TX_SET);
}
if((int)rx != NC)
{
CMSDK_UART3->CTRL |= 0x2; /* RX enable */
GPIO_MAP[CMSDK_GPIO_SH1_UART3_RX_GPIO_NUM]->ALTFUNCSET |=
(1<<CMSDK_GPIO_ALTFUNC_SH1_UART3_RX_SET);
}
obj->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<<CMSDK_GPIO_ALTFUNC_UART4_TX_SET);
}
if((int)uart_rx != NC) {
CMSDK_UART4->CTRL |= 0x02; /* RX enable */
GPIO_MAP[CMSDK_GPIO_UART4_RX_GPIO_NUM]->ALTFUNCSET |=
(1<<CMSDK_GPIO_ALTFUNC_UART4_RX_SET);
}
CMSDK_UART4->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)

View File

@ -31,47 +31,44 @@
static const PinMap PinMap_SPI_SCLK[] = {
{SPI_SCLK , SPI_0, 0},
{CLCD_SCLK , SPI_1, 0},
{ADC_SCLK , SPI_2, 0},
{SHIELD_0_SPI_SCK , SPI_3, 0},
{SHIELD_1_SPI_SCK , SPI_4, 0},
{ADC_SCLK , SPI_2, ALTERNATE_FUNC},
{SHIELD_0_SPI_SCK , SPI_3, ALTERNATE_FUNC},
{SHIELD_1_SPI_SCK , SPI_4, ALTERNATE_FUNC},
{NC , NC , 0}
};
static const PinMap PinMap_SPI_MOSI[] = {
{SPI_MOSI, SPI_0, 0},
{CLCD_MOSI, SPI_1, 0},
{ADC_MOSI, SPI_2, 0},
{SHIELD_0_SPI_MOSI, SPI_3, 0},
{SHIELD_1_SPI_MOSI, SPI_4, 0},
{SPI_MOSI , SPI_0, 0},
{CLCD_MOSI , SPI_1, 0},
{ADC_MOSI , SPI_2, ALTERNATE_FUNC},
{SHIELD_0_SPI_MOSI, SPI_3, ALTERNATE_FUNC},
{SHIELD_1_SPI_MOSI, SPI_4, ALTERNATE_FUNC},
{NC , NC , 0}
};
static const PinMap PinMap_SPI_MISO[] = {
{SPI_MISO, SPI_0, 0},
{CLCD_MISO, SPI_1, 0},
{ADC_MISO, SPI_2, 0},
{SHIELD_0_SPI_MISO, SPI_3, 0},
{SHIELD_1_SPI_MISO, SPI_4, 0},
{SPI_MISO , SPI_0, 0},
{CLCD_MISO , SPI_1, 0},
{ADC_MISO , SPI_2, ALTERNATE_FUNC},
{SHIELD_0_SPI_MISO, SPI_3, ALTERNATE_FUNC},
{SHIELD_1_SPI_MISO, SPI_4, ALTERNATE_FUNC},
{NC , NC , 0}
};
static const PinMap PinMap_SPI_SSEL[] = {
{SPI_SSEL, SPI_0, 0},
{CLCD_SSEL, SPI_1, 0},
{ADC_SSEL, SPI_2, 0},
{SHIELD_0_SPI_nCS, SPI_3, 0},
{SHIELD_1_SPI_nCS, SPI_4, 0},
{SPI_SSEL , SPI_0, 0},
{CLCD_SSEL , SPI_1, 0},
{ADC_SSEL , SPI_2, ALTERNATE_FUNC},
{SHIELD_0_SPI_nCS, SPI_3, ALTERNATE_FUNC},
{SHIELD_1_SPI_nCS, SPI_4, ALTERNATE_FUNC},
{NC , NC , 0}
};
extern CMSDK_GPIO_TypeDef* GPIO_MAP[];
static inline int ssp_disable(spi_t *obj);
static inline int ssp_enable(spi_t *obj);
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
{
int altfunction[4];
/* Determine the SPI to use */
SPIName spi_mosi = (SPIName)pinmap_peripheral(mosi, PinMap_SPI_MOSI);
SPIName spi_miso = (SPIName)pinmap_peripheral(miso, PinMap_SPI_MISO);
@ -83,12 +80,11 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
obj->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;
}
/* Set pin function as an alt-function */
if (mosi != NC) {
altfunction[0] = 1;
} else {
altfunction[0] = 0;
pin_function(mosi, ALTERNATE_FUNC);
}
if (miso != NC) {
altfunction[1] = 1;
} else {
altfunction[1] = 0;
pin_function(miso, ALTERNATE_FUNC);
}
if (sclk != NC) {
altfunction[2] = 1;
} else {
altfunction[2] = 0;
pin_function(sclk, ALTERNATE_FUNC);
}
if (ssel != NC) {
altfunction[3] = 1;
} else {
altfunction[3] = 0;
pin_function(ssel, ALTERNATE_FUNC);
}
/* 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]<<CMSDK_GPIO_ALTFUNC_ADC_MOSI_SPI_SET);
GPIO_MAP[CMSDK_GPIO_ADC_MISO_SPI_GPIO_NUM]->ALTFUNCSET |=
(altfunction[1]<<CMSDK_GPIO_ALTFUNC_ADC_MISO_SPI_SET);
GPIO_MAP[CMSDK_GPIO_ADC_SCK_SPI_GPIO_NUM]->ALTFUNCSET |=
(altfunction[2]<<CMSDK_GPIO_ALTFUNC_ADC_SCK_SPI_SET);
GPIO_MAP[CMSDK_GPIO_ADC_CS_SPI_GPIO_NUM]->ALTFUNCSET |=
(altfunction[3]<<CMSDK_GPIO_ALTFUNC_ADC_CS_SPI_SET);
break;
case (int)SPI_3: /* Shield 0 SPI */
GPIO_MAP[CMSDK_GPIO_SH0_MOSI_SPI_GPIO_NUM]->ALTFUNCSET |=
(altfunction[0]<<CMSDK_GPIO_ALTFUNC_SH0_MOSI_SPI_SET);
GPIO_MAP[CMSDK_GPIO_SH0_MISO_SPI_GPIO_NUM]->ALTFUNCSET |=
(altfunction[1]<<CMSDK_GPIO_ALTFUNC_SH0_MISO_SPI_SET);
GPIO_MAP[CMSDK_GPIO_SH0_SCK_SPI_GPIO_NUM]->ALTFUNCSET |=
(altfunction[2]<<CMSDK_GPIO_ALTFUNC_SH0_SCK_SPI_SET);
GPIO_MAP[CMSDK_GPIO_SH0_CS_SPI_GPIO_NUM]->ALTFUNCSET |=
(altfunction[3]<<CMSDK_GPIO_ALTFUNC_SH0_CS_SPI_SET);
break;
case (int)SPI_4: /* Shield 1 SPI */
GPIO_MAP[CMSDK_GPIO_SH1_MOSI_SPI_GPIO_NUM]->ALTFUNCSET |=
(altfunction[0]<<CMSDK_GPIO_ALTFUNC_SH1_MOSI_SPI_SET);
GPIO_MAP[CMSDK_GPIO_SH1_MISO_SPI_GPIO_NUM]->ALTFUNCSET |=
(altfunction[1]<<CMSDK_GPIO_ALTFUNC_SH1_MISO_SPI_SET);
GPIO_MAP[CMSDK_GPIO_SH1_SCK_SPI_GPIO_NUM]->ALTFUNCSET |=
(altfunction[2]<<CMSDK_GPIO_ALTFUNC_SH1_SCK_SPI_SET);
GPIO_MAP[CMSDK_GPIO_SH1_CS_SPI_GPIO_NUM]->ALTFUNCSET |=
(altfunction[3]<<CMSDK_GPIO_ALTFUNC_SH1_CS_SPI_SET);
break;
}
@ -208,14 +146,6 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
/* Enable the ssp channel */
ssp_enable(obj);
/* pin out the spi pins */
pinmap_pinout(mosi, PinMap_SPI_MOSI);
pinmap_pinout(miso, PinMap_SPI_MISO);
pinmap_pinout(sclk, PinMap_SPI_SCLK);
if (ssel != NC) {
pinmap_pinout(ssel, PinMap_SPI_SSEL);
}
}
void spi_free(spi_t *obj)
@ -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)

View File

@ -1988,7 +1988,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": ["ANALOGIN", "ETHERNET", "I2C", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "SERIAL", "SPI", "RTC"],
"release_versions": ["2", "5"]
},
"ARM_BEETLE_SOC": {