Refine coding style

pull/4974/head
ccli8 2017-07-05 17:40:55 +08:00 committed by adbridge
parent abd8dee9e5
commit 592f46b382
18 changed files with 1037 additions and 1073 deletions

View File

@ -14,26 +14,26 @@
* limitations under the License. * limitations under the License.
*/ */
#include "can_api.h" #include "can_api.h"
#include "m480_gpio.h" #include "m480_gpio.h"
#include "m480_can.h" #include "m480_can.h"
#if DEVICE_CAN #if DEVICE_CAN
#include <string.h> #include <string.h>
#include "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"
#include "PeripheralPins.h" #include "PeripheralPins.h"
#include "nu_modutil.h" #include "nu_modutil.h"
#include "nu_miscutil.h" #include "nu_miscutil.h"
#include "nu_bitutil.h" #include "nu_bitutil.h"
#include "mbed_critical.h" #include "mbed_critical.h"
#define NU_CAN_DEBUG 0 #define NU_CAN_DEBUG 0
#define CAN_NUM 2 #define CAN_NUM 2
static uint32_t can_irq_ids[CAN_NUM] = {0}; static uint32_t can_irq_ids[CAN_NUM] = {0};
static can_irq_handler can0_irq_handler; static can_irq_handler can0_irq_handler;
static can_irq_handler can1_irq_handler; static can_irq_handler can1_irq_handler;
extern uint32_t CAN_GetCANBitRate(CAN_T *tCAN); extern uint32_t CAN_GetCANBitRate(CAN_T *tCAN);
extern void CAN_EnterInitMode(CAN_T *tCAN, uint8_t u8Mask); extern void CAN_EnterInitMode(CAN_T *tCAN, uint8_t u8Mask);
@ -41,7 +41,7 @@ extern void CAN_LeaveInitMode(CAN_T *tCAN);
extern void CAN_LeaveTestMode(CAN_T *tCAN); extern void CAN_LeaveTestMode(CAN_T *tCAN);
extern void CAN_EnterTestMode(CAN_T *tCAN, uint8_t u8TestMask); extern void CAN_EnterTestMode(CAN_T *tCAN, uint8_t u8TestMask);
static const struct nu_modinit_s can_modinit_tab[] = { static const struct nu_modinit_s can_modinit_tab[] = {
{CAN_0, CAN0_MODULE, 0, 0, CAN0_RST, CAN0_IRQn, NULL}, {CAN_0, CAN0_MODULE, 0, 0, CAN0_RST, CAN0_IRQn, NULL},
{CAN_1, CAN1_MODULE, 0, 0, CAN1_RST, CAN1_IRQn, NULL}, {CAN_1, CAN1_MODULE, 0, 0, CAN1_RST, CAN1_IRQn, NULL},
@ -62,16 +62,15 @@ void can_init_freq(can_t *obj, PinName rd, PinName td, int hz)
// Reset this module // Reset this module
SYS_ResetModule(modinit->rsetidx); SYS_ResetModule(modinit->rsetidx);
NVIC_DisableIRQ(CAN0_IRQn); NVIC_DisableIRQ(CAN0_IRQn);
NVIC_DisableIRQ(CAN1_IRQn); NVIC_DisableIRQ(CAN1_IRQn);
// Enable IP clock // Enable IP clock
CLK_EnableModuleClock(modinit->clkidx); CLK_EnableModuleClock(modinit->clkidx);
if(obj->can == CAN_1) { if(obj->can == CAN_1) {
obj->index = 1; obj->index = 1;
} } else
else
obj->index = 0; obj->index = 0;
pinmap_pinout(td, PinMap_CAN_TD); pinmap_pinout(td, PinMap_CAN_TD);
@ -85,7 +84,7 @@ void can_init_freq(can_t *obj, PinName rd, PinName td, int hz)
CAN_Open((CAN_T *)NU_MODBASE(obj->can), hz, CAN_NORMAL_MODE); CAN_Open((CAN_T *)NU_MODBASE(obj->can), hz, CAN_NORMAL_MODE);
can_filter(obj, 0, 0, CANStandard, 0); can_filter(obj, 0, 0, CANStandard, 0);
} }
void can_init(can_t *obj, PinName rd, PinName td) void can_init(can_t *obj, PinName rd, PinName td)
{ {
@ -128,7 +127,7 @@ static void can_irq(CANName name, int id)
if(can->STATUS & CAN_STATUS_RXOK_Msk) { if(can->STATUS & CAN_STATUS_RXOK_Msk) {
can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/ can->STATUS &= ~CAN_STATUS_RXOK_Msk; /* Clear Rx Ok status*/
if(id) if(id)
can1_irq_handler(can_irq_ids[id] , IRQ_RX); can1_irq_handler(can_irq_ids[id], IRQ_RX);
else else
can0_irq_handler(can_irq_ids[id], IRQ_RX); can0_irq_handler(can_irq_ids[id], IRQ_RX);
} }
@ -136,7 +135,7 @@ static void can_irq(CANName name, int id)
if(can->STATUS & CAN_STATUS_TXOK_Msk) { if(can->STATUS & CAN_STATUS_TXOK_Msk) {
can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/ can->STATUS &= ~CAN_STATUS_TXOK_Msk; /* Clear Tx Ok status*/
if(id) if(id)
can1_irq_handler(can_irq_ids[id] , IRQ_TX); can1_irq_handler(can_irq_ids[id], IRQ_TX);
else else
can0_irq_handler(can_irq_ids[id], IRQ_TX); can0_irq_handler(can_irq_ids[id], IRQ_TX);
@ -147,21 +146,21 @@ static void can_irq(CANName name, int id)
/**************************/ /**************************/
if(can->STATUS & CAN_STATUS_EWARN_Msk) { if(can->STATUS & CAN_STATUS_EWARN_Msk) {
if(id) if(id)
can1_irq_handler(can_irq_ids[id] , IRQ_ERROR); can1_irq_handler(can_irq_ids[id], IRQ_ERROR);
else else
can0_irq_handler(can_irq_ids[id], IRQ_ERROR); can0_irq_handler(can_irq_ids[id], IRQ_ERROR);
} }
if(can->STATUS & CAN_STATUS_BOFF_Msk) { if(can->STATUS & CAN_STATUS_BOFF_Msk) {
if(id) if(id)
can1_irq_handler(can_irq_ids[id] , IRQ_BUS); can1_irq_handler(can_irq_ids[id], IRQ_BUS);
else else
can0_irq_handler(can_irq_ids[id], IRQ_BUS); can0_irq_handler(can_irq_ids[id], IRQ_BUS);
} }
} else if (u8IIDRstatus!=0) { } else if (u8IIDRstatus!=0) {
if(id) if(id)
can1_irq_handler(can_irq_ids[id] , IRQ_OVERRUN); can1_irq_handler(can_irq_ids[id], IRQ_OVERRUN);
else else
can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN); can0_irq_handler(can_irq_ids[id], IRQ_OVERRUN);
@ -171,7 +170,7 @@ static void can_irq(CANName name, int id)
can->WU_STATUS = 0; /* Write '0' to clear */ can->WU_STATUS = 0; /* Write '0' to clear */
if(id) if(id)
can1_irq_handler(can_irq_ids[id] , IRQ_WAKEUP); can1_irq_handler(can_irq_ids[id], IRQ_WAKEUP);
else else
can0_irq_handler(can_irq_ids[id], IRQ_WAKEUP); can0_irq_handler(can_irq_ids[id], IRQ_WAKEUP);
} }
@ -217,36 +216,32 @@ void can_irq_set(can_t *obj, CanIrqType irq, uint32_t enable)
u8Mask = ((enable != 0 )? CAN_CON_IE_Msk :0); u8Mask = ((enable != 0 )? CAN_CON_IE_Msk :0);
switch (irq) switch (irq) {
{ case IRQ_ERROR:
case IRQ_ERROR: case IRQ_BUS:
case IRQ_BUS: case IRQ_PASSIVE:
case IRQ_PASSIVE: u8Mask = u8Mask | CAN_CON_EIE_Msk | CAN_CON_SIE_Msk;
u8Mask = u8Mask | CAN_CON_EIE_Msk | CAN_CON_SIE_Msk; break;
break;
case IRQ_RX: case IRQ_RX:
case IRQ_TX: case IRQ_TX:
case IRQ_OVERRUN: case IRQ_OVERRUN:
case IRQ_WAKEUP: case IRQ_WAKEUP:
u8Mask = u8Mask | CAN_CON_SIE_Msk; u8Mask = u8Mask | CAN_CON_SIE_Msk;
break; break;
default: default:
break; break;
} }
CAN_EnterInitMode((CAN_T*)NU_MODBASE(obj->can), u8Mask); CAN_EnterInitMode((CAN_T*)NU_MODBASE(obj->can), u8Mask);
CAN_LeaveInitMode((CAN_T*)NU_MODBASE(obj->can)); CAN_LeaveInitMode((CAN_T*)NU_MODBASE(obj->can));
if(!obj->index) if(!obj->index) {
{
NVIC_SetVector(CAN0_IRQn, (uint32_t)&CAN0_IRQHandler); NVIC_SetVector(CAN0_IRQn, (uint32_t)&CAN0_IRQHandler);
NVIC_EnableIRQ(CAN0_IRQn); NVIC_EnableIRQ(CAN0_IRQn);
} } else {
else
{
NVIC_SetVector(CAN1_IRQn, (uint32_t)&CAN1_IRQHandler); NVIC_SetVector(CAN1_IRQn, (uint32_t)&CAN1_IRQHandler);
NVIC_EnableIRQ(CAN1_IRQn); NVIC_EnableIRQ(CAN1_IRQn);
} }
@ -271,7 +266,7 @@ int can_read(can_t *obj, CAN_Message *msg, int handle)
STR_CANMSG_T CMsg; STR_CANMSG_T CMsg;
if(!CAN_Receive((CAN_T *)(NU_MODBASE(obj->can)), handle, &CMsg)) if(!CAN_Receive((CAN_T *)(NU_MODBASE(obj->can)), handle, &CMsg))
return 0; return 0;
msg->format = (CANFormat)CMsg.IdType; msg->format = (CANFormat)CMsg.IdType;
msg->type = (CANType)!CMsg.FrameType; msg->type = (CANType)!CMsg.FrameType;
@ -285,37 +280,36 @@ int can_read(can_t *obj, CAN_Message *msg, int handle)
int can_mode(can_t *obj, CanMode mode) int can_mode(can_t *obj, CanMode mode)
{ {
int success = 0; int success = 0;
switch (mode) switch (mode) {
{ case MODE_RESET:
case MODE_RESET: CAN_LeaveTestMode((CAN_T*)NU_MODBASE(obj->can));
CAN_LeaveTestMode((CAN_T*)NU_MODBASE(obj->can)); success = 1;
success = 1; break;
break;
case MODE_NORMAL: case MODE_NORMAL:
CAN_EnterTestMode((CAN_T*)NU_MODBASE(obj->can), CAN_TEST_BASIC_Msk); CAN_EnterTestMode((CAN_T*)NU_MODBASE(obj->can), CAN_TEST_BASIC_Msk);
success = 1; success = 1;
break; break;
case MODE_SILENT: case MODE_SILENT:
CAN_EnterTestMode((CAN_T*)NU_MODBASE(obj->can), CAN_TEST_SILENT_Msk); CAN_EnterTestMode((CAN_T*)NU_MODBASE(obj->can), CAN_TEST_SILENT_Msk);
success = 1; success = 1;
break; break;
case MODE_TEST_LOCAL: case MODE_TEST_LOCAL:
case MODE_TEST_GLOBAL: case MODE_TEST_GLOBAL:
CAN_EnterTestMode((CAN_T*)NU_MODBASE(obj->can), CAN_TEST_LBACK_Msk); CAN_EnterTestMode((CAN_T*)NU_MODBASE(obj->can), CAN_TEST_LBACK_Msk);
success = 1; success = 1;
break; break;
case MODE_TEST_SILENT: case MODE_TEST_SILENT:
CAN_EnterTestMode((CAN_T*)NU_MODBASE(obj->can), CAN_TEST_SILENT_Msk | CAN_TEST_LBACK_Msk); CAN_EnterTestMode((CAN_T*)NU_MODBASE(obj->can), CAN_TEST_SILENT_Msk | CAN_TEST_LBACK_Msk);
success = 1; success = 1;
break; break;
default: default:
success = 0; success = 0;
break; break;
} }
@ -325,7 +319,7 @@ int can_mode(can_t *obj, CanMode mode)
int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle)
{ {
return CAN_SetRxMsg((CAN_T *)NU_MODBASE(obj->can), handle , (uint32_t)format, id); return CAN_SetRxMsg((CAN_T *)NU_MODBASE(obj->can), handle, (uint32_t)format, id);
} }

View File

@ -71,9 +71,9 @@ int dma_channel_allocate(uint32_t capabilities)
int i = nu_cto(dma_chn_mask); int i = nu_cto(dma_chn_mask);
if (i != 32) { if (i != 32) {
dma_chn_mask |= 1 << i; dma_chn_mask |= 1 << i;
memset(dma_chn_arr + i - NU_PDMA_CH_Pos, 0x00, sizeof (struct nu_dma_chn_s)); memset(dma_chn_arr + i - NU_PDMA_CH_Pos, 0x00, sizeof (struct nu_dma_chn_s));
return i; return i;
} }
// No channel available // No channel available

View File

@ -22,37 +22,37 @@
// NOTE: On ARMv7-M/ARMv8-M, instruction fetches are always little-endian. // NOTE: On ARMv7-M/ARMv8-M, instruction fetches are always little-endian.
static uint32_t FLASH_ALGO[] = { static uint32_t FLASH_ALGO[] = {
0x4603b530, 0x2164460c, 0x4df72059, 0x20166028, 0xf8c5070d, 0x20880100, 0x0100f8c5, 0xf8d006c0, 0x4603b530, 0x2164460c, 0x4df72059, 0x20166028, 0xf8c5070d, 0x20880100, 0x0100f8c5, 0xf8d006c0,
0xf0000100, 0xb9080001, 0xbd302001, 0x680048ef, 0x0004f040, 0x4580f04f, 0x0200f8c5, 0xf8d04628, 0xf0000100, 0xb9080001, 0xbd302001, 0x680048ef, 0x0004f040, 0x4580f04f, 0x0200f8c5, 0xf8d04628,
0xf0400204, 0xf8c50004, 0xbf000204, 0xf1a11e08, 0xd1fb0101, 0x680048e6, 0x0029f040, 0x60284de4, 0xf0400204, 0xf8c50004, 0xbf000204, 0xf1a11e08, 0xd1fb0101, 0x680048e6, 0x0029f040, 0x60284de4,
0x68004628, 0x0001f000, 0x2001b908, 0x48e0e7dd, 0xf0406800, 0x4dde0040, 0x20006028, 0x4601e7d5, 0x68004628, 0x0001f000, 0x2001b908, 0x48e0e7dd, 0xf0406800, 0x4dde0040, 0x20006028, 0x4601e7d5,
0x48dbbf00, 0xf0006900, 0x28000001, 0x48d8d1f9, 0xf0206800, 0x4ad60029, 0x20006010, 0x60104ad2, 0x48dbbf00, 0xf0006900, 0x28000001, 0x48d8d1f9, 0xf0206800, 0x4ad60029, 0x20006010, 0x60104ad2,
0x46014770, 0x48d2bf00, 0xf0006900, 0x28000001, 0x48cfd1f9, 0xf0406800, 0x4acd0040, 0x20226010, 0x46014770, 0x48d2bf00, 0xf0006900, 0x28000001, 0x48cfd1f9, 0xf0406800, 0x4acd0040, 0x20226010,
0xf02160d0, 0x60500003, 0x1f00f5b1, 0x48c9d101, 0x20016090, 0x61104ac6, 0x8f60f3bf, 0x48c4bf00, 0xf02160d0, 0x60500003, 0x1f00f5b1, 0x48c9d101, 0x20016090, 0x61104ac6, 0x8f60f3bf, 0x48c4bf00,
0xf0006900, 0x28000001, 0x48c1d1f9, 0xf0006800, 0xb1380040, 0x680048be, 0x0040f040, 0x60104abc, 0xf0006900, 0x28000001, 0x48c1d1f9, 0xf0006800, 0xb1380040, 0x680048be, 0x0040f040, 0x60104abc,
0x47702001, 0xe7fc2000, 0x4603b570, 0x2500460c, 0x4629e009, 0xf8531c6d, 0xf7ff0021, 0x1e06ffc2, 0x47702001, 0xe7fc2000, 0x4603b570, 0x2500460c, 0x4629e009, 0xf8531c6d, 0xf7ff0021, 0x1e06ffc2,
0x4630d001, 0x42a5bd70, 0x2000d3f3, 0xb570e7fa, 0x460b4604, 0x22004615, 0xf1034629, 0xf020000f, 0x4630d001, 0x42a5bd70, 0x2000d3f3, 0xb570e7fa, 0x460b4604, 0x22004615, 0xf1034629, 0xf020000f,
0xbf00030f, 0x690048aa, 0x0001f000, 0xd1f92800, 0x680048a7, 0x0040f040, 0x60304ea5, 0x000ff024, 0xbf00030f, 0x690048aa, 0x0001f000, 0xd1f92800, 0x680048a7, 0x0040f040, 0x60304ea5, 0x000ff024,
0x20276070, 0x461060f0, 0xf8511c52, 0x4ea00020, 0x60303680, 0x1c524610, 0x0020f851, 0xf8c64e9c, 0x20276070, 0x461060f0, 0xf8511c52, 0x4ea00020, 0x60303680, 0x1c524610, 0x0020f851, 0xf8c64e9c,
0x46100084, 0xf8511c52, 0x4e990020, 0x60303688, 0x1c524610, 0x0020f851, 0x60301d36, 0x4e942001, 0x46100084, 0xf8511c52, 0x4e990020, 0x60303688, 0x1c524610, 0x0020f851, 0x60301d36, 0x4e942001,
0x3b106130, 0xbf00e02c, 0x30c04891, 0xf0006800, 0x28000030, 0x4610d1f8, 0xf8511c52, 0x4e8c0020, 0x3b106130, 0xbf00e02c, 0x30c04891, 0xf0006800, 0x28000030, 0x4610d1f8, 0xf8511c52, 0x4e8c0020,
0x60303680, 0x1c524610, 0x0020f851, 0xf8c64e88, 0xbf000084, 0x30c04886, 0xf0006800, 0x280000c0, 0x60303680, 0x1c524610, 0x0020f851, 0xf8c64e88, 0xbf000084, 0x30c04886, 0xf0006800, 0x280000c0,
0x4610d1f8, 0xf8511c52, 0x4e810020, 0x60303688, 0x1c524610, 0x0020f851, 0xf8c64e7d, 0x3b10008c, 0x4610d1f8, 0xf8511c52, 0x4e810020, 0x60303688, 0x1c524610, 0x0020f851, 0xf8c64e7d, 0x3b10008c,
0xd1d02b00, 0x487abf00, 0xf0006900, 0x28000001, 0xbd70d1f9, 0x4603b510, 0xf0201cc8, 0xbf000103, 0xd1d02b00, 0x487abf00, 0xf0006900, 0x28000001, 0xbd70d1f9, 0x4603b510, 0xf0201cc8, 0xbf000103,
0x69004873, 0x0001f000, 0xd1f92800, 0x68004870, 0x0040f040, 0x60204c6e, 0x60e02021, 0xf023e020, 0x69004873, 0x0001f000, 0xd1f92800, 0x68004870, 0x0040f040, 0x60204c6e, 0x60e02021, 0xf023e020,
0x4c6b0003, 0x68106060, 0x200160a0, 0xf3bf6120, 0xbf008f60, 0x69004866, 0x0001f000, 0xd1f92800, 0x4c6b0003, 0x68106060, 0x200160a0, 0xf3bf6120, 0xbf008f60, 0x69004866, 0x0001f000, 0xd1f92800,
0x68004863, 0x0040f000, 0x4861b138, 0xf0406800, 0x4c5f0040, 0x20016020, 0x1d1bbd10, 0x1f091d12, 0x68004863, 0x0040f000, 0x4861b138, 0xf0406800, 0x4c5f0040, 0x20016020, 0x1d1bbd10, 0x1f091d12,
0xd1dc2900, 0xe7f72000, 0x47f0e92d, 0x460c4605, 0xf04f4616, 0x46c20800, 0x4855bf00, 0xf0006900, 0xd1dc2900, 0xe7f72000, 0x47f0e92d, 0x460c4605, 0xf04f4616, 0x46c20800, 0x4855bf00, 0xf0006900,
0x28000001, 0x4852d1f9, 0xf0406800, 0x49500040, 0x1ce06008, 0x0403f020, 0xf3c5e02f, 0xb9600008, 0x28000001, 0x4852d1f9, 0xf0406800, 0x49500040, 0x1ce06008, 0x0403f020, 0xf3c5e02f, 0xb9600008,
0x7f00f5b4, 0xf44fd309, 0xeb067700, 0x46390208, 0xf7ff4628, 0x4682ff2c, 0xf3c5e016, 0xb9580008, 0x7f00f5b4, 0xf44fd309, 0xeb067700, 0x46390208, 0xf7ff4628, 0x4682ff2c, 0xf3c5e016, 0xb9580008,
0xd3092c10, 0x070ff024, 0x0208eb06, 0x46284639, 0xff1df7ff, 0xe0074682, 0xeb064627, 0x46390208, 0xd3092c10, 0x070ff024, 0x0208eb06, 0x46284639, 0xff1df7ff, 0xe0074682, 0xeb064627, 0x46390208,
0xf7ff4628, 0x4682ff87, 0x44b8443d, 0xf1ba1be4, 0xd0020f00, 0xe8bd2001, 0x2c0087f0, 0x2000d1cd, 0xf7ff4628, 0x4682ff87, 0x44b8443d, 0xf1ba1be4, 0xd0020f00, 0xe8bd2001, 0x2c0087f0, 0x2000d1cd,
0xb510e7f9, 0xf0231ccb, 0xbf000103, 0x691b4b30, 0x0301f003, 0xd1f92b00, 0x681b4b2d, 0x0340f043, 0xb510e7f9, 0xf0231ccb, 0xbf000103, 0x691b4b30, 0x0301f003, 0xd1f92b00, 0x681b4b2d, 0x0340f043,
0x60234c2b, 0x60e32300, 0xf020e025, 0x4c280303, 0x23006063, 0x230160a3, 0xf3bf6123, 0xbf008f60, 0x60234c2b, 0x60e32300, 0xf020e025, 0x4c280303, 0x23006063, 0x230160a3, 0xf3bf6123, 0xbf008f60,
0x691b4b23, 0x0301f003, 0xd1f92b00, 0x681b4b20, 0x0340f003, 0x4b1eb133, 0xf043681b, 0x4c1c0340, 0x691b4b23, 0x0301f003, 0xd1f92b00, 0x681b4b20, 0x0340f003, 0x4b1eb133, 0xf043681b, 0x4c1c0340,
0xbd106023, 0x689b4b1a, 0x42a36814, 0xe7f8d000, 0x1d121d00, 0x29001f09, 0xbf00d1d7, 0xb510e7f1, 0xbd106023, 0x689b4b1a, 0x42a36814, 0xe7f8d000, 0x1d121d00, 0x29001f09, 0xbf00d1d7, 0xb510e7f1,
0x48134603, 0xf0006e00, 0xb1680002, 0x65034810, 0x65826541, 0x4c0e2001, 0xbf0065e0, 0x6e00480c, 0x48134603, 0xf0006e00, 0xb1680002, 0x65034810, 0x65826541, 0x4c0e2001, 0xbf0065e0, 0x6e00480c,
0x0001f000, 0xd1f92800, 0x6e004809, 0x0004f000, 0x2002b908, 0x4806bd10, 0xf0006e00, 0xb1080002, 0x0001f000, 0xd1f92800, 0x6e004809, 0x0004f000, 0x2002b908, 0x4806bd10, 0xf0006e00, 0xb1080002,
0xe7f72001, 0xe7f52000, 0x40000100, 0x40000200, 0x4000c000, 0x0055aa03, 0x00000000, 0xe7f72001, 0xe7f52000, 0x40000100, 0x40000200, 0x4000c000, 0x0055aa03, 0x00000000,
}; };
static const flash_algo_t flash_algo_config = { static const flash_algo_t flash_algo_config = {

View File

@ -70,16 +70,16 @@ void gpio_dir(gpio_t *obj, PinDirection direction)
uint32_t mode_intern = GPIO_MODE_INPUT; uint32_t mode_intern = GPIO_MODE_INPUT;
switch (direction) { switch (direction) {
case PIN_INPUT: case PIN_INPUT:
mode_intern = GPIO_MODE_INPUT; mode_intern = GPIO_MODE_INPUT;
break; break;
case PIN_OUTPUT: case PIN_OUTPUT:
mode_intern = GPIO_MODE_OUTPUT; mode_intern = GPIO_MODE_OUTPUT;
break; break;
default: default:
return; return;
} }
GPIO_SetMode(gpio_base, 1 << pin_index, mode_intern); GPIO_SetMode(gpio_base, 1 << pin_index, mode_intern);

View File

@ -117,7 +117,7 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
uint32_t port_index_debounce = NU_PINNAME_TO_PORT(*debounce_pos); uint32_t port_index_debounce = NU_PINNAME_TO_PORT(*debounce_pos);
if (pin_index == pin_index_debunce && if (pin_index == pin_index_debunce &&
port_index == port_index_debounce) { port_index == port_index_debounce) {
// Configure de-bounce clock source and sampling cycle time // Configure de-bounce clock source and sampling cycle time
GPIO_SET_DEBOUNCE_TIME(MBED_CONF_M480_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_M480_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE); GPIO_SET_DEBOUNCE_TIME(MBED_CONF_M480_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, MBED_CONF_M480_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE);
GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index);
@ -157,27 +157,25 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
GPIO_T *gpio_base = NU_PORT_BASE(port_index); GPIO_T *gpio_base = NU_PORT_BASE(port_index);
switch (event) { switch (event) {
case IRQ_RISE: case IRQ_RISE:
if (enable) { if (enable) {
GPIO_EnableInt(gpio_base, pin_index, GPIO_INT_RISING); GPIO_EnableInt(gpio_base, pin_index, GPIO_INT_RISING);
} } else {
else { gpio_base->INTEN &= ~(GPIO_INT_RISING << pin_index);
gpio_base->INTEN &= ~(GPIO_INT_RISING << pin_index); }
} break;
break;
case IRQ_FALL: case IRQ_FALL:
if (enable) { if (enable) {
GPIO_EnableInt(gpio_base, pin_index, GPIO_INT_FALLING); GPIO_EnableInt(gpio_base, pin_index, GPIO_INT_FALLING);
} } else {
else { gpio_base->INTEN &= ~(GPIO_INT_FALLING << pin_index);
gpio_base->INTEN &= ~(GPIO_INT_FALLING << pin_index); }
} break;
break;
case IRQ_NONE: case IRQ_NONE:
default: default:
break; break;
} }
} }

View File

@ -228,10 +228,9 @@ int i2c_byte_write(i2c_t *obj, int data)
data_[0] = data & 0xFF; data_[0] = data & 0xFF;
if (i2c_do_tran(obj, data_, 1, 0, 0) == 1 && if (i2c_do_tran(obj, data_, 1, 0, 0) == 1 &&
! (obj->i2c.tran_ctrl & TRANCTRL_LASTDATANAKED)) { ! (obj->i2c.tran_ctrl & TRANCTRL_LASTDATANAKED)) {
return 1; return 1;
} } else {
else {
return 0; return 0;
} }
} }
@ -337,8 +336,7 @@ static int i2c_set_int(i2c_t *obj, int inten)
if (inten) { if (inten) {
i2c_enable_int(obj); i2c_enable_int(obj);
} } else {
else {
i2c_disable_int(obj); i2c_disable_int(obj);
} }
@ -384,8 +382,7 @@ static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastd
MY_I2C_2 = obj->i2c; MY_I2C_2 = obj->i2c;
while (1); while (1);
#endif #endif
} } else {
else {
i2c_disable_int(obj); i2c_disable_int(obj);
tran_len = obj->i2c.tran_pos - obj->i2c.tran_beg; tran_len = obj->i2c.tran_pos - obj->i2c.tran_beg;
obj->i2c.tran_beg = NULL; obj->i2c.tran_beg = NULL;
@ -410,8 +407,7 @@ static int i2c_do_trsn(i2c_t *obj, uint32_t i2c_ctl, int sync)
MY_I2C_2 = obj->i2c; MY_I2C_2 = obj->i2c;
while (1); while (1);
#endif #endif
} } else {
else {
#if 1 #if 1
// NOTE: Avoid duplicate Start/Stop. Otherwise, we may meet strange error. // NOTE: Avoid duplicate Start/Stop. Otherwise, we may meet strange error.
uint32_t status = I2C_GET_STATUS(i2c_base); uint32_t status = I2C_GET_STATUS(i2c_base);
@ -421,15 +417,13 @@ static int i2c_do_trsn(i2c_t *obj, uint32_t i2c_ctl, int sync)
case 0x10: // Master Repeat Start case 0x10: // Master Repeat Start
if (i2c_ctl & I2C_CTL0_STA_Msk) { if (i2c_ctl & I2C_CTL0_STA_Msk) {
return 0; return 0;
} } else {
else {
break; break;
} }
case 0xF8: // Bus Released case 0xF8: // Bus Released
if ((i2c_ctl & (I2C_CTL0_STA_Msk | I2C_CTL0_STO_Msk)) == I2C_CTL0_STO_Msk) { if ((i2c_ctl & (I2C_CTL0_STA_Msk | I2C_CTL0_STO_Msk)) == I2C_CTL0_STO_Msk) {
return 0; return 0;
} } else {
else {
break; break;
} }
} }
@ -601,217 +595,203 @@ static void i2c_irq(i2c_t *obj)
#if NU_I2C_DEBUG #if NU_I2C_DEBUG
if (MY_I2C_STATUS_POS < (sizeof (MY_I2C_STATUS) / sizeof (MY_I2C_STATUS[0]))) { if (MY_I2C_STATUS_POS < (sizeof (MY_I2C_STATUS) / sizeof (MY_I2C_STATUS[0]))) {
MY_I2C_STATUS[MY_I2C_STATUS_POS ++] = status; MY_I2C_STATUS[MY_I2C_STATUS_POS ++] = status;
} } else {
else {
memset(MY_I2C_STATUS, 0x00, sizeof (MY_I2C_STATUS)); memset(MY_I2C_STATUS, 0x00, sizeof (MY_I2C_STATUS));
MY_I2C_STATUS_POS = 0; MY_I2C_STATUS_POS = 0;
} }
#endif #endif
switch (status) { switch (status) {
// Master Transmit // Master Transmit
case 0x28: // Master Transmit Data ACK case 0x28: // Master Transmit Data ACK
case 0x18: // Master Transmit Address ACK case 0x18: // Master Transmit Address ACK
case 0x08: // Start case 0x08: // Start
case 0x10: // Master Repeat Start case 0x10: // Master Repeat Start
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) { if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) { if (obj->i2c.tran_pos < obj->i2c.tran_end) {
I2C_SET_DATA(i2c_base, *obj->i2c.tran_pos ++); I2C_SET_DATA(i2c_base, *obj->i2c.tran_pos ++);
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk); I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
} } else {
else { i2c_fsm_tranfini(obj, 0);
i2c_fsm_tranfini(obj, 0);
}
} }
else { } else {
i2c_disable_int(obj); i2c_disable_int(obj);
} }
break; break;
case 0x30: // Master Transmit Data NACK case 0x30: // Master Transmit Data NACK
i2c_fsm_tranfini(obj, 1); i2c_fsm_tranfini(obj, 1);
break; break;
case 0x20: // Master Transmit Address NACK case 0x20: // Master Transmit Address NACK
i2c_fsm_tranfini(obj, 1); i2c_fsm_tranfini(obj, 1);
break; break;
case 0x38: // Master Arbitration Lost case 0x38: // Master Arbitration Lost
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk); i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
break; break;
case 0x48: // Master Receive Address NACK case 0x48: // Master Receive Address NACK
i2c_fsm_tranfini(obj, 1); i2c_fsm_tranfini(obj, 1);
break; break;
case 0x40: // Master Receive Address ACK case 0x40: // Master Receive Address ACK
case 0x50: // Master Receive Data ACK case 0x50: // Master Receive Data ACK
case 0x58: // Master Receive Data NACK case 0x58: // Master Receive Data NACK
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) { if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) { if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x50 || status == 0x58) { if (status == 0x50 || status == 0x58) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base); *obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
} }
if (status == 0x58) { if (status == 0x58) {
#if NU_I2C_DEBUG #if NU_I2C_DEBUG
if (obj->i2c.tran_pos != obj->i2c.tran_end) { if (obj->i2c.tran_pos != obj->i2c.tran_end) {
MY_I2C = obj->i2c; MY_I2C = obj->i2c;
while (1); while (1);
} }
#endif #endif
i2c_fsm_tranfini(obj, 1); i2c_fsm_tranfini(obj, 1);
} } else {
else {
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) {
// Last data
i2c_ctl &= ~I2C_CTL0_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
}
}
else {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
break;
}
}
else {
i2c_disable_int(obj);
}
break;
//case 0x00: // Bus error
// Slave Transmit
case 0xB8: // Slave Transmit Data ACK
case 0xA8: // Slave Transmit Address ACK
case 0xB0: // Slave Transmit Arbitration Lost
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk; uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
I2C_SET_DATA(i2c_base, *obj->i2c.tran_pos ++); obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) {
if (obj->i2c.tran_pos == obj->i2c.tran_end &&
obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) {
// Last data // Last data
i2c_ctl &= ~I2C_CTL0_AA_Msk; i2c_ctl &= ~I2C_CTL0_AA_Msk;
} }
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl); I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
} }
else { } else {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED; obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
break;
}
}
else {
i2c_disable_int(obj); i2c_disable_int(obj);
break;
} }
obj->i2c.slaveaddr_state = ReadAddressed; } else {
break; i2c_disable_int(obj);
//case 0xA0: // Slave Transmit Repeat Start or Stop }
case 0xC0: // Slave Transmit Data NACK break;
case 0xC8: // Slave Transmit Last Data ACK
obj->i2c.slaveaddr_state = NoData;
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
break;
// Slave Receive //case 0x00: // Bus error
case 0x80: // Slave Receive Data ACK
case 0x88: // Slave Receive Data NACK
case 0x60: // Slave Receive Address ACK
case 0x68: // Slave Receive Arbitration Lost
obj->i2c.slaveaddr_state = WriteAddressed;
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x80 || status == 0x88) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
}
if (status == 0x88) { // Slave Transmit
case 0xB8: // Slave Transmit Data ACK
case 0xA8: // Slave Transmit Address ACK
case 0xB0: // Slave Transmit Arbitration Lost
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
I2C_SET_DATA(i2c_base, *obj->i2c.tran_pos ++);
if (obj->i2c.tran_pos == obj->i2c.tran_end &&
obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) {
// Last data
i2c_ctl &= ~I2C_CTL0_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
} else {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
break;
}
} else {
i2c_disable_int(obj);
}
obj->i2c.slaveaddr_state = ReadAddressed;
break;
//case 0xA0: // Slave Transmit Repeat Start or Stop
case 0xC0: // Slave Transmit Data NACK
case 0xC8: // Slave Transmit Last Data ACK
obj->i2c.slaveaddr_state = NoData;
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
break;
// Slave Receive
case 0x80: // Slave Receive Data ACK
case 0x88: // Slave Receive Data NACK
case 0x60: // Slave Receive Address ACK
case 0x68: // Slave Receive Arbitration Lost
obj->i2c.slaveaddr_state = WriteAddressed;
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x80 || status == 0x88) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
}
if (status == 0x88) {
#if NU_I2C_DEBUG #if NU_I2C_DEBUG
if (obj->i2c.tran_pos != obj->i2c.tran_end) { if (obj->i2c.tran_pos != obj->i2c.tran_end) {
MY_I2C = obj->i2c; MY_I2C = obj->i2c;
while (1); while (1);
} }
#endif #endif
obj->i2c.slaveaddr_state = NoData; obj->i2c.slaveaddr_state = NoData;
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk); i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
} } else {
else { uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk; if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) { obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) {
// Last data // Last data
i2c_ctl &= ~I2C_CTL0_AA_Msk; i2c_ctl &= ~I2C_CTL0_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
} }
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
} }
else { } else {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED; obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
break;
}
}
else {
i2c_disable_int(obj); i2c_disable_int(obj);
break;
} }
break; } else {
//case 0xA0: // Slave Receive Repeat Start or Stop i2c_disable_int(obj);
}
break;
//case 0xA0: // Slave Receive Repeat Start or Stop
// GC mode // GC mode
//case 0xA0: // GC mode Repeat Start or Stop //case 0xA0: // GC mode Repeat Start or Stop
case 0x90: // GC mode Data ACK case 0x90: // GC mode Data ACK
case 0x98: // GC mode Data NACK case 0x98: // GC mode Data NACK
case 0x70: // GC mode Address ACK case 0x70: // GC mode Address ACK
case 0x78: // GC mode Arbitration Lost case 0x78: // GC mode Arbitration Lost
obj->i2c.slaveaddr_state = WriteAddressed; obj->i2c.slaveaddr_state = WriteAddressed;
if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) { if ((obj->i2c.tran_ctrl & TRANCTRL_STARTED) && obj->i2c.tran_pos) {
if (obj->i2c.tran_pos < obj->i2c.tran_end) { if (obj->i2c.tran_pos < obj->i2c.tran_end) {
if (status == 0x90 || status == 0x98) { if (status == 0x90 || status == 0x98) {
*obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base); *obj->i2c.tran_pos ++ = I2C_GET_DATA(i2c_base);
} }
if (status == 0x98) { if (status == 0x98) {
#if NU_I2C_DEBUG #if NU_I2C_DEBUG
if (obj->i2c.tran_pos != obj->i2c.tran_end) { if (obj->i2c.tran_pos != obj->i2c.tran_end) {
MY_I2C = obj->i2c; MY_I2C = obj->i2c;
while (1); while (1);
} }
#endif #endif
obj->i2c.slaveaddr_state = NoData; obj->i2c.slaveaddr_state = NoData;
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk); i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
} } else {
else { uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk;
uint32_t i2c_ctl = I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk; if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
if ((obj->i2c.tran_end - obj->i2c.tran_pos) == 1 &&
obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) { obj->i2c.tran_ctrl & TRANCTRL_NAKLASTDATA) {
// Last data // Last data
i2c_ctl &= ~I2C_CTL0_AA_Msk; i2c_ctl &= ~I2C_CTL0_AA_Msk;
}
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
} }
I2C_SET_CONTROL_REG(i2c_base, i2c_ctl);
} }
else { } else {
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED; obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;
i2c_disable_int(obj);
break;
}
}
else {
i2c_disable_int(obj); i2c_disable_int(obj);
break;
} }
break; } else {
i2c_disable_int(obj);
}
break;
case 0xF8: // Bus Released case 0xF8: // Bus Released
break; break;
default: default:
i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk); i2c_fsm_reset(obj, I2C_CTL0_SI_Msk | I2C_CTL0_AA_Msk);
} }
} }
@ -864,105 +844,99 @@ uint32_t i2c_irq_handler_asynch(i2c_t *obj)
I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c); I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
uint32_t status = I2C_GET_STATUS(i2c_base); uint32_t status = I2C_GET_STATUS(i2c_base);
switch (status) { switch (status) {
case 0x08: // Start case 0x08: // Start
case 0x10: {// Master Repeat Start case 0x10: {// Master Repeat Start
if (obj->tx_buff.buffer && obj->tx_buff.pos < obj->tx_buff.length) { if (obj->tx_buff.buffer && obj->tx_buff.pos < obj->tx_buff.length) {
I2C_SET_DATA(i2c_base, (i2c_addr2data(obj->i2c.address, 0))); I2C_SET_DATA(i2c_base, (i2c_addr2data(obj->i2c.address, 0)));
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_SI_Msk); I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_SI_Msk);
} else if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
I2C_SET_DATA(i2c_base, (i2c_addr2data(obj->i2c.address, 1)));
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_SI_Msk);
} else {
event = I2C_EVENT_TRANSFER_COMPLETE;
if (obj->i2c.stop) {
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk);
} }
else if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
I2C_SET_DATA(i2c_base, (i2c_addr2data(obj->i2c.address, 1)));
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_SI_Msk);
}
else {
event = I2C_EVENT_TRANSFER_COMPLETE;
if (obj->i2c.stop) {
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk);
}
}
break;
} }
break;
}
case 0x18: // Master Transmit Address ACK case 0x18: // Master Transmit Address ACK
case 0x28: // Master Transmit Data ACK case 0x28: // Master Transmit Data ACK
if (obj->tx_buff.buffer && obj->tx_buff.pos < obj->tx_buff.length) { if (obj->tx_buff.buffer && obj->tx_buff.pos < obj->tx_buff.length) {
uint8_t *tx = (uint8_t *)obj->tx_buff.buffer; uint8_t *tx = (uint8_t *)obj->tx_buff.buffer;
I2C_SET_DATA(i2c_base, tx[obj->tx_buff.pos ++]); I2C_SET_DATA(i2c_base, tx[obj->tx_buff.pos ++]);
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_SI_Msk); I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_SI_Msk);
} } else if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
else if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk);
}
else {
event = I2C_EVENT_TRANSFER_COMPLETE;
if (obj->i2c.stop) {
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk);
}
}
break;
case 0x20: // Master Transmit Address NACK
event = I2C_EVENT_ERROR_NO_SLAVE;
if (obj->i2c.stop) {
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk);
}
break;
case 0x30: // Master Transmit Data NACK
if (obj->tx_buff.buffer && obj->tx_buff.pos < obj->tx_buff.length) {
event = I2C_EVENT_TRANSFER_EARLY_NACK;
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk);
}
else if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk);
}
else {
event = I2C_EVENT_TRANSFER_COMPLETE;
if (obj->i2c.stop) {
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk);
}
}
break;
case 0x38: // Master Arbitration Lost
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_SI_Msk); // Enter not addressed SLV mode
event = I2C_EVENT_ERROR;
break;
case 0x50: // Master Receive Data ACK
if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
uint8_t *rx = (uint8_t *) obj->rx_buff.buffer;
rx[obj->rx_buff.pos ++] = I2C_GET_DATA(((I2C_T *) NU_MODBASE(obj->i2c.i2c)));
}
case 0x40: // Master Receive Address ACK
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_SI_Msk | ((obj->rx_buff.pos != obj->rx_buff.length - 1) ? I2C_CTL0_AA_Msk : 0));
break;
case 0x48: // Master Receive Address NACK
event = I2C_EVENT_ERROR_NO_SLAVE;
if (obj->i2c.stop) {
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk);
}
break;
case 0x58: // Master Receive Data NACK
if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
uint8_t *rx = (uint8_t *) obj->rx_buff.buffer;
rx[obj->rx_buff.pos ++] = I2C_GET_DATA(((I2C_T *) NU_MODBASE(obj->i2c.i2c)));
}
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk); I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk);
break; } else {
event = I2C_EVENT_TRANSFER_COMPLETE;
case 0x00: // Bus error
event = I2C_EVENT_ERROR;
i2c_reset(obj);
break;
default:
event = I2C_EVENT_ERROR;
if (obj->i2c.stop) { if (obj->i2c.stop) {
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk); I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk);
} }
}
break;
case 0x20: // Master Transmit Address NACK
event = I2C_EVENT_ERROR_NO_SLAVE;
if (obj->i2c.stop) {
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk);
}
break;
case 0x30: // Master Transmit Data NACK
if (obj->tx_buff.buffer && obj->tx_buff.pos < obj->tx_buff.length) {
event = I2C_EVENT_TRANSFER_EARLY_NACK;
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk);
} else if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk);
} else {
event = I2C_EVENT_TRANSFER_COMPLETE;
if (obj->i2c.stop) {
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk);
}
}
break;
case 0x38: // Master Arbitration Lost
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_SI_Msk); // Enter not addressed SLV mode
event = I2C_EVENT_ERROR;
break;
case 0x50: // Master Receive Data ACK
if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
uint8_t *rx = (uint8_t *) obj->rx_buff.buffer;
rx[obj->rx_buff.pos ++] = I2C_GET_DATA(((I2C_T *) NU_MODBASE(obj->i2c.i2c)));
}
case 0x40: // Master Receive Address ACK
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_SI_Msk | ((obj->rx_buff.pos != obj->rx_buff.length - 1) ? I2C_CTL0_AA_Msk : 0));
break;
case 0x48: // Master Receive Address NACK
event = I2C_EVENT_ERROR_NO_SLAVE;
if (obj->i2c.stop) {
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk);
}
break;
case 0x58: // Master Receive Data NACK
if (obj->rx_buff.buffer && obj->rx_buff.pos < obj->rx_buff.length) {
uint8_t *rx = (uint8_t *) obj->rx_buff.buffer;
rx[obj->rx_buff.pos ++] = I2C_GET_DATA(((I2C_T *) NU_MODBASE(obj->i2c.i2c)));
}
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk);
break;
case 0x00: // Bus error
event = I2C_EVENT_ERROR;
i2c_reset(obj);
break;
default:
event = I2C_EVENT_ERROR;
if (obj->i2c.stop) {
I2C_SET_CONTROL_REG(i2c_base, I2C_CTL0_STO_Msk | I2C_CTL0_SI_Msk);
}
} }
if (event) { if (event) {
@ -1009,8 +983,7 @@ static void i2c_enable_vector_interrupt(i2c_t *obj, uint32_t handler, int enable
if (enable) { if (enable) {
NVIC_SetVector(modinit->irq_n, handler); NVIC_SetVector(modinit->irq_n, handler);
i2c_enable_int(obj); i2c_enable_int(obj);
} } else {
else {
i2c_disable_int(obj); i2c_disable_int(obj);
} }

View File

@ -130,19 +130,16 @@ timestamp_t lp_ticker_read()
// When TIMER_CNT approaches TIMER_CMP and will wrap soon, we may get carry but TIMER_CNT not wrapped. Handle carefully carry == 1 && TIMER_CNT is near TIMER_CMP. // When TIMER_CNT approaches TIMER_CMP and will wrap soon, we may get carry but TIMER_CNT not wrapped. Handle carefully carry == 1 && TIMER_CNT is near TIMER_CMP.
if (carry && minor_clks > (TMR2_CLK_PER_TMR2_INT / 2)) { if (carry && minor_clks > (TMR2_CLK_PER_TMR2_INT / 2)) {
major_minor_clks = (counter_major + 1) * TMR2_CLK_PER_TMR2_INT; major_minor_clks = (counter_major + 1) * TMR2_CLK_PER_TMR2_INT;
} } else {
else {
major_minor_clks = (counter_major + carry) * TMR2_CLK_PER_TMR2_INT + minor_clks; major_minor_clks = (counter_major + carry) * TMR2_CLK_PER_TMR2_INT + minor_clks;
} }
core_util_critical_section_exit(); core_util_critical_section_exit();
} } while (minor_clks == 0 || minor_clks == TMR2_CLK_PER_TMR2_INT);
while (minor_clks == 0 || minor_clks == TMR2_CLK_PER_TMR2_INT);
// Add power-down compensation // Add power-down compensation
return ((uint64_t) major_minor_clks * US_PER_SEC / TMR2_CLK_PER_SEC / US_PER_TICK); return ((uint64_t) major_minor_clks * US_PER_SEC / TMR2_CLK_PER_SEC / US_PER_TICK);
} } while (0);
while (0);
} }
void lp_ticker_set_interrupt(timestamp_t timestamp) void lp_ticker_set_interrupt(timestamp_t timestamp)
@ -163,8 +160,7 @@ void lp_ticker_set_interrupt(timestamp_t timestamp)
if (delta > 0) { if (delta > 0) {
cd_major_minor_clks = (uint64_t) delta * US_PER_TICK * TMR3_CLK_PER_SEC / US_PER_SEC; cd_major_minor_clks = (uint64_t) delta * US_PER_TICK * TMR3_CLK_PER_SEC / US_PER_SEC;
lp_ticker_arm_cd(); lp_ticker_arm_cd();
} } else {
else {
cd_major_minor_clks = cd_minor_clks = 0; cd_major_minor_clks = cd_minor_clks = 0;
/** /**
* This event was in the past. Set the interrupt as pending, but don't process it here. * This event was in the past. Set the interrupt as pending, but don't process it here.
@ -199,8 +195,7 @@ static void tmr3_vec(void)
if (cd_major_minor_clks == 0) { if (cd_major_minor_clks == 0) {
// NOTE: lp_ticker_set_interrupt() may get called in lp_ticker_irq_handler(); // NOTE: lp_ticker_set_interrupt() may get called in lp_ticker_irq_handler();
lp_ticker_irq_handler(); lp_ticker_irq_handler();
} } else {
else {
lp_ticker_arm_cd(); lp_ticker_arm_cd();
} }
} }

View File

@ -47,26 +47,26 @@ void pin_mode(PinName pin, PinMode mode)
uint32_t mode_intern = GPIO_MODE_INPUT; uint32_t mode_intern = GPIO_MODE_INPUT;
switch (mode) { switch (mode) {
case PullUp: case PullUp:
mode_intern = GPIO_MODE_INPUT; mode_intern = GPIO_MODE_INPUT;
break; break;
case PullDown: case PullDown:
case PullNone: case PullNone:
// NOTE: Not support // NOTE: Not support
return; return;
case PushPull: case PushPull:
mode_intern = GPIO_MODE_OUTPUT; mode_intern = GPIO_MODE_OUTPUT;
break; break;
case OpenDrain: case OpenDrain:
mode_intern = GPIO_MODE_OPEN_DRAIN; mode_intern = GPIO_MODE_OPEN_DRAIN;
break; break;
case Quasi: case Quasi:
mode_intern = GPIO_MODE_QUASI; mode_intern = GPIO_MODE_QUASI;
break; break;
} }
GPIO_SetMode(gpio_base, 1 << pin_index, mode_intern); GPIO_SetMode(gpio_base, 1 << pin_index, mode_intern);

View File

@ -291,7 +291,8 @@ void serial_free(serial_t *obj)
} }
} }
void serial_baud(serial_t *obj, int baudrate) { void serial_baud(serial_t *obj, int baudrate)
{
// Flush Tx FIFO. Otherwise, output data may get lost on this change. // Flush Tx FIFO. Otherwise, output data may get lost on this change.
while (! UART_IS_TX_EMPTY((UART_T *) NU_MODBASE(obj->serial.uart))); while (! UART_IS_TX_EMPTY((UART_T *) NU_MODBASE(obj->serial.uart)));
@ -299,7 +300,8 @@ void serial_baud(serial_t *obj, int baudrate) {
UART_Open((UART_T *) NU_MODBASE(obj->serial.uart), baudrate); UART_Open((UART_T *) NU_MODBASE(obj->serial.uart), baudrate);
} }
void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) { void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
{
// Flush Tx FIFO. Otherwise, output data may get lost on this change. // Flush Tx FIFO. Otherwise, output data may get lost on this change.
while (! UART_IS_TX_EMPTY((UART_T *) NU_MODBASE(obj->serial.uart))); while (! UART_IS_TX_EMPTY((UART_T *) NU_MODBASE(obj->serial.uart)));
@ -313,18 +315,18 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
obj->serial.stopbits = stop_bits; obj->serial.stopbits = stop_bits;
uint32_t databits_intern = (data_bits == 5) ? UART_WORD_LEN_5 : uint32_t databits_intern = (data_bits == 5) ? UART_WORD_LEN_5 :
(data_bits == 6) ? UART_WORD_LEN_6 : (data_bits == 6) ? UART_WORD_LEN_6 :
(data_bits == 7) ? UART_WORD_LEN_7 : (data_bits == 7) ? UART_WORD_LEN_7 :
UART_WORD_LEN_8; UART_WORD_LEN_8;
uint32_t parity_intern = (parity == ParityOdd || parity == ParityForced1) ? UART_PARITY_ODD : uint32_t parity_intern = (parity == ParityOdd || parity == ParityForced1) ? UART_PARITY_ODD :
(parity == ParityEven || parity == ParityForced0) ? UART_PARITY_EVEN : (parity == ParityEven || parity == ParityForced0) ? UART_PARITY_EVEN :
UART_PARITY_NONE; UART_PARITY_NONE;
uint32_t stopbits_intern = (stop_bits == 2) ? UART_STOP_BIT_2 : UART_STOP_BIT_1; uint32_t stopbits_intern = (stop_bits == 2) ? UART_STOP_BIT_2 : UART_STOP_BIT_1;
UART_SetLine_Config((UART_T *) NU_MODBASE(obj->serial.uart), UART_SetLine_Config((UART_T *) NU_MODBASE(obj->serial.uart),
0, // Don't change baudrate 0, // Don't change baudrate
databits_intern, databits_intern,
parity_intern, parity_intern,
stopbits_intern); stopbits_intern);
} }
#if DEVICE_SERIAL_FC #if DEVICE_SERIAL_FC
@ -537,25 +539,25 @@ int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx
pdma_base->CHCTL |= 1 << obj->serial.dma_chn_id_tx; // Enable this DMA channel pdma_base->CHCTL |= 1 << obj->serial.dma_chn_id_tx; // Enable this DMA channel
PDMA_SetTransferMode(obj->serial.dma_chn_id_tx, PDMA_SetTransferMode(obj->serial.dma_chn_id_tx,
((struct nu_uart_var *) modinit->var)->pdma_perp_tx, // Peripheral connected to this PDMA ((struct nu_uart_var *) modinit->var)->pdma_perp_tx, // Peripheral connected to this PDMA
0, // Scatter-gather disabled 0, // Scatter-gather disabled
0); // Scatter-gather descriptor address 0); // Scatter-gather descriptor address
PDMA_SetTransferCnt(obj->serial.dma_chn_id_tx, PDMA_SetTransferCnt(obj->serial.dma_chn_id_tx,
(tx_width == 8) ? PDMA_WIDTH_8 : (tx_width == 16) ? PDMA_WIDTH_16 : PDMA_WIDTH_32, (tx_width == 8) ? PDMA_WIDTH_8 : (tx_width == 16) ? PDMA_WIDTH_16 : PDMA_WIDTH_32,
tx_length); tx_length);
PDMA_SetTransferAddr(obj->serial.dma_chn_id_tx, PDMA_SetTransferAddr(obj->serial.dma_chn_id_tx,
(uint32_t) tx, // NOTE: (uint32_t) tx, // NOTE:
// NUC472: End of source address // NUC472: End of source address
// M451: Start of source address // M451: Start of source address
// M480: Start of source address // M480: Start of source address
PDMA_SAR_INC, // Source address incremental PDMA_SAR_INC, // Source address incremental
(uint32_t) NU_MODBASE(obj->serial.uart), // Destination address (uint32_t) NU_MODBASE(obj->serial.uart), // Destination address
PDMA_DAR_FIX); // Destination address fixed PDMA_DAR_FIX); // Destination address fixed
PDMA_SetBurstType(obj->serial.dma_chn_id_tx, PDMA_SetBurstType(obj->serial.dma_chn_id_tx,
PDMA_REQ_SINGLE, // Single mode PDMA_REQ_SINGLE, // Single mode
0); // Burst size 0); // Burst size
PDMA_EnableInt(obj->serial.dma_chn_id_tx, PDMA_EnableInt(obj->serial.dma_chn_id_tx,
PDMA_INT_TRANS_DONE); // Interrupt type PDMA_INT_TRANS_DONE); // Interrupt type
// Register DMA event handler // Register DMA event handler
dma_set_handler(obj->serial.dma_chn_id_tx, (uint32_t) uart_dma_handler_tx, (uint32_t) obj, DMA_EVENT_ALL); dma_set_handler(obj->serial.dma_chn_id_tx, (uint32_t) uart_dma_handler_tx, (uint32_t) obj, DMA_EVENT_ALL);
serial_tx_enable_interrupt(obj, handler, 1); serial_tx_enable_interrupt(obj, handler, 1);
@ -573,8 +575,8 @@ void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_widt
serial_check_dma_usage(&obj->serial.dma_usage_rx, &obj->serial.dma_chn_id_rx); serial_check_dma_usage(&obj->serial.dma_usage_rx, &obj->serial.dma_chn_id_rx);
// DMA doesn't support char match, so fall back to IRQ if it is requested. // DMA doesn't support char match, so fall back to IRQ if it is requested.
if (obj->serial.dma_usage_rx != DMA_USAGE_NEVER && if (obj->serial.dma_usage_rx != DMA_USAGE_NEVER &&
(event & SERIAL_EVENT_RX_CHARACTER_MATCH) && (event & SERIAL_EVENT_RX_CHARACTER_MATCH) &&
char_match != SERIAL_RESERVED_CHAR_MATCH) { char_match != SERIAL_RESERVED_CHAR_MATCH) {
obj->serial.dma_usage_rx = DMA_USAGE_NEVER; obj->serial.dma_usage_rx = DMA_USAGE_NEVER;
dma_channel_free(obj->serial.dma_chn_id_rx); dma_channel_free(obj->serial.dma_chn_id_rx);
obj->serial.dma_chn_id_rx = DMA_ERROR_OUT_OF_CHANNELS; obj->serial.dma_chn_id_rx = DMA_ERROR_OUT_OF_CHANNELS;
@ -598,25 +600,25 @@ void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_widt
pdma_base->CHCTL |= 1 << obj->serial.dma_chn_id_rx; // Enable this DMA channel pdma_base->CHCTL |= 1 << obj->serial.dma_chn_id_rx; // Enable this DMA channel
PDMA_SetTransferMode(obj->serial.dma_chn_id_rx, PDMA_SetTransferMode(obj->serial.dma_chn_id_rx,
((struct nu_uart_var *) modinit->var)->pdma_perp_rx, // Peripheral connected to this PDMA ((struct nu_uart_var *) modinit->var)->pdma_perp_rx, // Peripheral connected to this PDMA
0, // Scatter-gather disabled 0, // Scatter-gather disabled
0); // Scatter-gather descriptor address 0); // Scatter-gather descriptor address
PDMA_SetTransferCnt(obj->serial.dma_chn_id_rx, PDMA_SetTransferCnt(obj->serial.dma_chn_id_rx,
(rx_width == 8) ? PDMA_WIDTH_8 : (rx_width == 16) ? PDMA_WIDTH_16 : PDMA_WIDTH_32, (rx_width == 8) ? PDMA_WIDTH_8 : (rx_width == 16) ? PDMA_WIDTH_16 : PDMA_WIDTH_32,
rx_length); rx_length);
PDMA_SetTransferAddr(obj->serial.dma_chn_id_rx, PDMA_SetTransferAddr(obj->serial.dma_chn_id_rx,
(uint32_t) NU_MODBASE(obj->serial.uart), // Source address (uint32_t) NU_MODBASE(obj->serial.uart), // Source address
PDMA_SAR_FIX, // Source address fixed PDMA_SAR_FIX, // Source address fixed
(uint32_t) rx, // NOTE: (uint32_t) rx, // NOTE:
// NUC472: End of destination address // NUC472: End of destination address
// M451: Start of destination address // M451: Start of destination address
// M480: Start of destination address // M480: Start of destination address
PDMA_DAR_INC); // Destination address incremental PDMA_DAR_INC); // Destination address incremental
PDMA_SetBurstType(obj->serial.dma_chn_id_rx, PDMA_SetBurstType(obj->serial.dma_chn_id_rx,
PDMA_REQ_SINGLE, // Single mode PDMA_REQ_SINGLE, // Single mode
0); // Burst size 0); // Burst size
PDMA_EnableInt(obj->serial.dma_chn_id_rx, PDMA_EnableInt(obj->serial.dma_chn_id_rx,
PDMA_INT_TRANS_DONE); // Interrupt type PDMA_INT_TRANS_DONE); // Interrupt type
// Register DMA event handler // Register DMA event handler
dma_set_handler(obj->serial.dma_chn_id_rx, (uint32_t) uart_dma_handler_rx, (uint32_t) obj, DMA_EVENT_ALL); dma_set_handler(obj->serial.dma_chn_id_rx, (uint32_t) uart_dma_handler_rx, (uint32_t) obj, DMA_EVENT_ALL);
serial_rx_enable_interrupt(obj, handler, 1); serial_rx_enable_interrupt(obj, handler, 1);
@ -955,13 +957,13 @@ static int serial_write_async(serial_t *obj)
int n_words = 0; int n_words = 0;
while (obj->tx_buff.pos < obj->tx_buff.length && tx_fifo_free >= bytes_per_word) { while (obj->tx_buff.pos < obj->tx_buff.length && tx_fifo_free >= bytes_per_word) {
switch (bytes_per_word) { switch (bytes_per_word) {
case 4: case 4:
UART_WRITE(((UART_T *) NU_MODBASE(obj->serial.uart)), *tx ++); UART_WRITE(((UART_T *) NU_MODBASE(obj->serial.uart)), *tx ++);
UART_WRITE(((UART_T *) NU_MODBASE(obj->serial.uart)), *tx ++); UART_WRITE(((UART_T *) NU_MODBASE(obj->serial.uart)), *tx ++);
case 2: case 2:
UART_WRITE(((UART_T *) NU_MODBASE(obj->serial.uart)), *tx ++); UART_WRITE(((UART_T *) NU_MODBASE(obj->serial.uart)), *tx ++);
case 1: case 1:
UART_WRITE(((UART_T *) NU_MODBASE(obj->serial.uart)), *tx ++); UART_WRITE(((UART_T *) NU_MODBASE(obj->serial.uart)), *tx ++);
} }
n_words ++; n_words ++;
@ -993,13 +995,13 @@ static int serial_read_async(serial_t *obj)
int n_words = 0; int n_words = 0;
while (obj->rx_buff.pos < obj->rx_buff.length && rx_fifo_busy >= bytes_per_word) { while (obj->rx_buff.pos < obj->rx_buff.length && rx_fifo_busy >= bytes_per_word) {
switch (bytes_per_word) { switch (bytes_per_word) {
case 4: case 4:
*rx ++ = UART_READ(((UART_T *) NU_MODBASE(obj->serial.uart))); *rx ++ = UART_READ(((UART_T *) NU_MODBASE(obj->serial.uart)));
*rx ++ = UART_READ(((UART_T *) NU_MODBASE(obj->serial.uart))); *rx ++ = UART_READ(((UART_T *) NU_MODBASE(obj->serial.uart)));
case 2: case 2:
*rx ++ = UART_READ(((UART_T *) NU_MODBASE(obj->serial.uart))); *rx ++ = UART_READ(((UART_T *) NU_MODBASE(obj->serial.uart)));
case 1: case 1:
*rx ++ = UART_READ(((UART_T *) NU_MODBASE(obj->serial.uart))); *rx ++ = UART_READ(((UART_T *) NU_MODBASE(obj->serial.uart)));
} }
n_words ++; n_words ++;
@ -1007,15 +1009,15 @@ static int serial_read_async(serial_t *obj)
obj->rx_buff.pos ++; obj->rx_buff.pos ++;
if ((obj->serial.event & SERIAL_EVENT_RX_CHARACTER_MATCH) && if ((obj->serial.event & SERIAL_EVENT_RX_CHARACTER_MATCH) &&
obj->char_match != SERIAL_RESERVED_CHAR_MATCH) { obj->char_match != SERIAL_RESERVED_CHAR_MATCH) {
uint8_t *rx_cmp = rx; uint8_t *rx_cmp = rx;
switch (bytes_per_word) { switch (bytes_per_word) {
case 4: case 4:
rx_cmp -= 2; rx_cmp -= 2;
case 2: case 2:
rx_cmp --; rx_cmp --;
case 1: case 1:
rx_cmp --; rx_cmp --;
} }
if (*rx_cmp == obj->char_match) { if (*rx_cmp == obj->char_match) {
obj->char_found = 1; obj->char_found = 1;
@ -1094,27 +1096,26 @@ static void serial_enable_interrupt(serial_t *obj, SerialIrq irq, uint32_t enabl
var->obj = obj; var->obj = obj;
switch (irq) { switch (irq) {
// NOTE: Setting inten_msk first to avoid race condition // NOTE: Setting inten_msk first to avoid race condition
case RxIrq: case RxIrq:
obj->serial.inten_msk = obj->serial.inten_msk | (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk); obj->serial.inten_msk = obj->serial.inten_msk | (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk);
UART_ENABLE_INT(((UART_T *) NU_MODBASE(obj->serial.uart)), (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk)); UART_ENABLE_INT(((UART_T *) NU_MODBASE(obj->serial.uart)), (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk));
break; break;
case TxIrq: case TxIrq:
obj->serial.inten_msk = obj->serial.inten_msk | UART_INTEN_THREIEN_Msk; obj->serial.inten_msk = obj->serial.inten_msk | UART_INTEN_THREIEN_Msk;
UART_ENABLE_INT(((UART_T *) NU_MODBASE(obj->serial.uart)), UART_INTEN_THREIEN_Msk); UART_ENABLE_INT(((UART_T *) NU_MODBASE(obj->serial.uart)), UART_INTEN_THREIEN_Msk);
break; break;
} }
} } else { // disable
else { // disable
switch (irq) { switch (irq) {
case RxIrq: case RxIrq:
UART_DISABLE_INT(((UART_T *) NU_MODBASE(obj->serial.uart)), (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk)); UART_DISABLE_INT(((UART_T *) NU_MODBASE(obj->serial.uart)), (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk));
obj->serial.inten_msk = obj->serial.inten_msk & ~(UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk); obj->serial.inten_msk = obj->serial.inten_msk & ~(UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk);
break; break;
case TxIrq: case TxIrq:
UART_DISABLE_INT(((UART_T *) NU_MODBASE(obj->serial.uart)), UART_INTEN_THREIEN_Msk); UART_DISABLE_INT(((UART_T *) NU_MODBASE(obj->serial.uart)), UART_INTEN_THREIEN_Msk);
obj->serial.inten_msk = obj->serial.inten_msk & ~UART_INTEN_THREIEN_Msk; obj->serial.inten_msk = obj->serial.inten_msk & ~UART_INTEN_THREIEN_Msk;
break; break;
} }
} }
} }
@ -1140,8 +1141,7 @@ static void serial_check_dma_usage(DMAUsage *dma_usage, int *dma_ch)
if (*dma_ch == DMA_ERROR_OUT_OF_CHANNELS) { if (*dma_ch == DMA_ERROR_OUT_OF_CHANNELS) {
*dma_usage = DMA_USAGE_NEVER; *dma_usage = DMA_USAGE_NEVER;
} }
} } else {
else {
dma_channel_free(*dma_ch); dma_channel_free(*dma_ch);
*dma_ch = DMA_ERROR_OUT_OF_CHANNELS; *dma_ch = DMA_ERROR_OUT_OF_CHANNELS;
} }
@ -1152,12 +1152,12 @@ static int serial_is_irq_en(serial_t *obj, SerialIrq irq)
int inten_msk = 0; int inten_msk = 0;
switch (irq) { switch (irq) {
case RxIrq: case RxIrq:
inten_msk = obj->serial.inten_msk & (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk); inten_msk = obj->serial.inten_msk & (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk);
break; break;
case TxIrq: case TxIrq:
inten_msk = obj->serial.inten_msk & UART_INTEN_THREIEN_Msk; inten_msk = obj->serial.inten_msk & UART_INTEN_THREIEN_Msk;
break; break;
} }
return !! inten_msk; return !! inten_msk;

View File

@ -79,8 +79,7 @@ static void mbed_enter_sleep(struct sleep_s *obj)
SYS_UnlockReg(); SYS_UnlockReg();
CLK_PowerDown(); CLK_PowerDown();
SYS_LockReg(); SYS_LockReg();
} } else { // CPU halt mode (HIRC/HXT enabled, LIRC/LXT enabled)
else { // CPU halt mode (HIRC/HXT enabled, LIRC/LXT enabled)
SYS_UnlockReg(); SYS_UnlockReg();
CLK_Idle(); CLK_Idle();
SYS_LockReg(); SYS_LockReg();

View File

@ -102,7 +102,8 @@ static const struct nu_modinit_s spi_modinit_tab[] = {
{NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL} {NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL}
}; };
void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) { void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
{
// Determine which SPI_x the pins are used for // Determine which SPI_x the pins are used for
uint32_t spi_mosi = pinmap_peripheral(mosi, PinMap_SPI_MOSI); uint32_t spi_mosi = pinmap_peripheral(mosi, PinMap_SPI_MOSI);
uint32_t spi_miso = pinmap_peripheral(miso, PinMap_SPI_MISO); uint32_t spi_miso = pinmap_peripheral(miso, PinMap_SPI_MISO);
@ -189,10 +190,10 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
SPI_DISABLE(spi_base); SPI_DISABLE(spi_base);
SPI_Open(spi_base, SPI_Open(spi_base,
slave ? SPI_SLAVE : SPI_MASTER, slave ? SPI_SLAVE : SPI_MASTER,
(mode == 0) ? SPI_MODE_0 : (mode == 1) ? SPI_MODE_1 : (mode == 2) ? SPI_MODE_2 : SPI_MODE_3, (mode == 0) ? SPI_MODE_0 : (mode == 1) ? SPI_MODE_1 : (mode == 2) ? SPI_MODE_2 : SPI_MODE_3,
bits, bits,
SPI_GetBusClock(spi_base)); SPI_GetBusClock(spi_base));
// NOTE: Hardcode to be MSB first. // NOTE: Hardcode to be MSB first.
SPI_SET_MSB_FIRST(spi_base); SPI_SET_MSB_FIRST(spi_base);
@ -201,12 +202,10 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
if (obj->spi.pin_ssel != NC) { if (obj->spi.pin_ssel != NC) {
// Configure SS as low active. // Configure SS as low active.
SPI_EnableAutoSS(spi_base, SPI_SS, SPI_SS_ACTIVE_LOW); SPI_EnableAutoSS(spi_base, SPI_SS, SPI_SS_ACTIVE_LOW);
} } else {
else {
SPI_DisableAutoSS(spi_base); SPI_DisableAutoSS(spi_base);
} }
} } else {
else {
// Slave // Slave
// Configure SS as low active. // Configure SS as low active.
spi_base->SSCTL &= ~SPI_SSCTL_SSACTPOL_Msk; spi_base->SSCTL &= ~SPI_SSCTL_SSACTPOL_Msk;
@ -247,6 +246,21 @@ int spi_master_write(spi_t *obj, int value)
return value2; return value2;
} }
int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length)
{
int total = (tx_length > rx_length) ? tx_length : rx_length;
for (int i = 0; i < total; i++) {
char out = (i < tx_length) ? tx_buffer[i] : 0xff;
char in = spi_master_write(obj, out);
if (i < rx_length) {
rx_buffer[i] = in;
}
}
return total;
}
#if DEVICE_SPISLAVE #if DEVICE_SPISLAVE
int spi_slave_receive(spi_t *obj) int spi_slave_receive(spi_t *obj)
{ {
@ -294,7 +308,7 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
// (1) No DMA support for non-8 multiple data width. // (1) No DMA support for non-8 multiple data width.
// (2) tx length >= rx length. Otherwise, as tx DMA is done, no bus activity for remaining rx. // (2) tx length >= rx length. Otherwise, as tx DMA is done, no bus activity for remaining rx.
if ((data_width % 8) || if ((data_width % 8) ||
(tx_length < rx_length)) { (tx_length < rx_length)) {
obj->spi.dma_usage = DMA_USAGE_NEVER; obj->spi.dma_usage = DMA_USAGE_NEVER;
dma_channel_free(obj->spi.dma_chn_id_tx); dma_channel_free(obj->spi.dma_chn_id_tx);
obj->spi.dma_chn_id_tx = DMA_ERROR_OUT_OF_CHANNELS; obj->spi.dma_chn_id_tx = DMA_ERROR_OUT_OF_CHANNELS;
@ -324,48 +338,48 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx,
// Configure tx DMA // Configure tx DMA
pdma_base->CHCTL |= 1 << obj->spi.dma_chn_id_tx; // Enable this DMA channel pdma_base->CHCTL |= 1 << obj->spi.dma_chn_id_tx; // Enable this DMA channel
PDMA_SetTransferMode(obj->spi.dma_chn_id_tx, PDMA_SetTransferMode(obj->spi.dma_chn_id_tx,
((struct nu_spi_var *) modinit->var)->pdma_perp_tx, // Peripheral connected to this PDMA ((struct nu_spi_var *) modinit->var)->pdma_perp_tx, // Peripheral connected to this PDMA
0, // Scatter-gather disabled 0, // Scatter-gather disabled
0); // Scatter-gather descriptor address 0); // Scatter-gather descriptor address
PDMA_SetTransferCnt(obj->spi.dma_chn_id_tx, PDMA_SetTransferCnt(obj->spi.dma_chn_id_tx,
(data_width == 8) ? PDMA_WIDTH_8 : (data_width == 16) ? PDMA_WIDTH_16 : PDMA_WIDTH_32, (data_width == 8) ? PDMA_WIDTH_8 : (data_width == 16) ? PDMA_WIDTH_16 : PDMA_WIDTH_32,
tx_length); tx_length);
PDMA_SetTransferAddr(obj->spi.dma_chn_id_tx, PDMA_SetTransferAddr(obj->spi.dma_chn_id_tx,
(uint32_t) tx, // NOTE: (uint32_t) tx, // NOTE:
// NUC472: End of source address // NUC472: End of source address
// M451/M480: Start of source address // M451/M480: Start of source address
PDMA_SAR_INC, // Source address incremental PDMA_SAR_INC, // Source address incremental
(uint32_t) &spi_base->TX, // Destination address (uint32_t) &spi_base->TX, // Destination address
PDMA_DAR_FIX); // Destination address fixed PDMA_DAR_FIX); // Destination address fixed
PDMA_SetBurstType(obj->spi.dma_chn_id_tx, PDMA_SetBurstType(obj->spi.dma_chn_id_tx,
PDMA_REQ_SINGLE, // Single mode PDMA_REQ_SINGLE, // Single mode
0); // Burst size 0); // Burst size
PDMA_EnableInt(obj->spi.dma_chn_id_tx, PDMA_EnableInt(obj->spi.dma_chn_id_tx,
PDMA_INT_TRANS_DONE); // Interrupt type PDMA_INT_TRANS_DONE); // Interrupt type
// Register DMA event handler // Register DMA event handler
dma_set_handler(obj->spi.dma_chn_id_tx, (uint32_t) spi_dma_handler_tx, (uint32_t) obj, DMA_EVENT_ALL); dma_set_handler(obj->spi.dma_chn_id_tx, (uint32_t) spi_dma_handler_tx, (uint32_t) obj, DMA_EVENT_ALL);
// Configure rx DMA // Configure rx DMA
pdma_base->CHCTL |= 1 << obj->spi.dma_chn_id_rx; // Enable this DMA channel pdma_base->CHCTL |= 1 << obj->spi.dma_chn_id_rx; // Enable this DMA channel
PDMA_SetTransferMode(obj->spi.dma_chn_id_rx, PDMA_SetTransferMode(obj->spi.dma_chn_id_rx,
((struct nu_spi_var *) modinit->var)->pdma_perp_rx, // Peripheral connected to this PDMA ((struct nu_spi_var *) modinit->var)->pdma_perp_rx, // Peripheral connected to this PDMA
0, // Scatter-gather disabled 0, // Scatter-gather disabled
0); // Scatter-gather descriptor address 0); // Scatter-gather descriptor address
PDMA_SetTransferCnt(obj->spi.dma_chn_id_rx, PDMA_SetTransferCnt(obj->spi.dma_chn_id_rx,
(data_width == 8) ? PDMA_WIDTH_8 : (data_width == 16) ? PDMA_WIDTH_16 : PDMA_WIDTH_32, (data_width == 8) ? PDMA_WIDTH_8 : (data_width == 16) ? PDMA_WIDTH_16 : PDMA_WIDTH_32,
rx_length); rx_length);
PDMA_SetTransferAddr(obj->spi.dma_chn_id_rx, PDMA_SetTransferAddr(obj->spi.dma_chn_id_rx,
(uint32_t) &spi_base->RX, // Source address (uint32_t) &spi_base->RX, // Source address
PDMA_SAR_FIX, // Source address fixed PDMA_SAR_FIX, // Source address fixed
(uint32_t) rx, // NOTE: (uint32_t) rx, // NOTE:
// NUC472: End of destination address // NUC472: End of destination address
// M451/M480: Start of destination address // M451/M480: Start of destination address
PDMA_DAR_INC); // Destination address incremental PDMA_DAR_INC); // Destination address incremental
PDMA_SetBurstType(obj->spi.dma_chn_id_rx, PDMA_SetBurstType(obj->spi.dma_chn_id_rx,
PDMA_REQ_SINGLE, // Single mode PDMA_REQ_SINGLE, // Single mode
0); // Burst size 0); // Burst size
PDMA_EnableInt(obj->spi.dma_chn_id_rx, PDMA_EnableInt(obj->spi.dma_chn_id_rx,
PDMA_INT_TRANS_DONE); // Interrupt type PDMA_INT_TRANS_DONE); // Interrupt type
// Register DMA event handler // Register DMA event handler
dma_set_handler(obj->spi.dma_chn_id_rx, (uint32_t) spi_dma_handler_rx, (uint32_t) obj, DMA_EVENT_ALL); dma_set_handler(obj->spi.dma_chn_id_rx, (uint32_t) spi_dma_handler_rx, (uint32_t) obj, DMA_EVENT_ALL);
@ -495,8 +509,7 @@ static void spi_enable_vector_interrupt(spi_t *obj, uint32_t handler, uint8_t en
if (enable) { if (enable) {
NVIC_SetVector(modinit->irq_n, handler); NVIC_SetVector(modinit->irq_n, handler);
NVIC_EnableIRQ(modinit->irq_n); NVIC_EnableIRQ(modinit->irq_n);
} } else {
else {
NVIC_DisableIRQ(modinit->irq_n); NVIC_DisableIRQ(modinit->irq_n);
} }
} }
@ -510,8 +523,7 @@ static void spi_master_enable_interrupt(spi_t *obj, uint8_t enable)
SPI_SetFIFO(spi_base, fifo_depth / 2, fifo_depth / 2); SPI_SetFIFO(spi_base, fifo_depth / 2, fifo_depth / 2);
// Enable tx/rx FIFO threshold interrupt // Enable tx/rx FIFO threshold interrupt
SPI_EnableInt(spi_base, SPI_FIFO_RXTH_INT_MASK | SPI_FIFO_TXTH_INT_MASK); SPI_EnableInt(spi_base, SPI_FIFO_RXTH_INT_MASK | SPI_FIFO_TXTH_INT_MASK);
} } else {
else {
SPI_DisableInt(spi_base, SPI_FIFO_RXTH_INT_MASK | SPI_FIFO_TXTH_INT_MASK); SPI_DisableInt(spi_base, SPI_FIFO_RXTH_INT_MASK | SPI_FIFO_TXTH_INT_MASK);
} }
} }
@ -576,21 +588,20 @@ static uint32_t spi_master_write_asynch(spi_t *obj, uint32_t tx_limit)
if (spi_is_tx_complete(obj)) { if (spi_is_tx_complete(obj)) {
// Transmit dummy as transmit buffer is empty // Transmit dummy as transmit buffer is empty
SPI_WRITE_TX(spi_base, 0); SPI_WRITE_TX(spi_base, 0);
} } else {
else {
switch (bytes_per_word) { switch (bytes_per_word) {
case 4: case 4:
SPI_WRITE_TX(spi_base, nu_get32_le(tx)); SPI_WRITE_TX(spi_base, nu_get32_le(tx));
tx += 4; tx += 4;
break; break;
case 2: case 2:
SPI_WRITE_TX(spi_base, nu_get16_le(tx)); SPI_WRITE_TX(spi_base, nu_get16_le(tx));
tx += 2; tx += 2;
break; break;
case 1: case 1:
SPI_WRITE_TX(spi_base, *((uint8_t *) tx)); SPI_WRITE_TX(spi_base, *((uint8_t *) tx));
tx += 1; tx += 1;
break; break;
} }
obj->tx_buff.pos ++; obj->tx_buff.pos ++;
@ -628,24 +639,23 @@ static uint32_t spi_master_read_asynch(spi_t *obj)
if (spi_is_rx_complete(obj)) { if (spi_is_rx_complete(obj)) {
// Disregard as receive buffer is full // Disregard as receive buffer is full
SPI_READ_RX(spi_base); SPI_READ_RX(spi_base);
} } else {
else {
switch (bytes_per_word) { switch (bytes_per_word) {
case 4: { case 4: {
uint32_t val = SPI_READ_RX(spi_base); uint32_t val = SPI_READ_RX(spi_base);
nu_set32_le(rx, val); nu_set32_le(rx, val);
rx += 4; rx += 4;
break; break;
} }
case 2: { case 2: {
uint16_t val = SPI_READ_RX(spi_base); uint16_t val = SPI_READ_RX(spi_base);
nu_set16_le(rx, val); nu_set16_le(rx, val);
rx += 2; rx += 2;
break; break;
} }
case 1: case 1:
*rx ++ = SPI_READ_RX(spi_base); *rx ++ = SPI_READ_RX(spi_base);
break; break;
} }
obj->rx_buff.pos ++; obj->rx_buff.pos ++;

View File

@ -122,18 +122,15 @@ uint32_t us_ticker_read()
// When TIMER_CNT approaches TIMER_CMP and will wrap soon, we may get carry but TIMER_CNT not wrapped. Hanlde carefully carry == 1 && TIMER_CNT is near TIMER_CMP. // When TIMER_CNT approaches TIMER_CMP and will wrap soon, we may get carry but TIMER_CNT not wrapped. Hanlde carefully carry == 1 && TIMER_CNT is near TIMER_CMP.
if (carry && minor_us > (US_PER_TMR0HIRES_INT / 2)) { if (carry && minor_us > (US_PER_TMR0HIRES_INT / 2)) {
major_minor_us = (counter_major + 1) * US_PER_TMR0HIRES_INT; major_minor_us = (counter_major + 1) * US_PER_TMR0HIRES_INT;
} } else {
else {
major_minor_us = (counter_major + carry) * US_PER_TMR0HIRES_INT + minor_us; major_minor_us = (counter_major + carry) * US_PER_TMR0HIRES_INT + minor_us;
} }
core_util_critical_section_exit(); core_util_critical_section_exit();
} } while (minor_us == 0 || minor_us == US_PER_TMR0HIRES_INT);
while (minor_us == 0 || minor_us == US_PER_TMR0HIRES_INT);
return (major_minor_us / US_PER_TICK); return (major_minor_us / US_PER_TICK);
} } while (0);
while (0);
} }
void us_ticker_disable_interrupt(void) void us_ticker_disable_interrupt(void)
@ -154,8 +151,7 @@ void us_ticker_set_interrupt(timestamp_t timestamp)
if (delta > 0) { if (delta > 0) {
cd_major_minor_us = delta * US_PER_TICK; cd_major_minor_us = delta * US_PER_TICK;
us_ticker_arm_cd(); us_ticker_arm_cd();
} } else {
else {
cd_major_minor_us = cd_minor_us = 0; cd_major_minor_us = cd_minor_us = 0;
/** /**
* This event was in the past. Set the interrupt as pending, but don't process it here. * This event was in the past. Set the interrupt as pending, but don't process it here.
@ -178,8 +174,7 @@ static void tmr1_vec(void)
if (cd_major_minor_us == 0) { if (cd_major_minor_us == 0) {
// NOTE: us_ticker_set_interrupt() may get called in us_ticker_irq_handler(); // NOTE: us_ticker_set_interrupt() may get called in us_ticker_irq_handler();
us_ticker_irq_handler(); us_ticker_irq_handler();
} } else {
else {
us_ticker_arm_cd(); us_ticker_arm_cd();
} }
} }