1:
9:
10:
14:
15:
16:
#include "AG903_errno.h"
17:
#include "AG903_intno.h"
18:
#include "gpio/gpiomgr.h"
19:
#include "gpio/gpioprm.h"
20:
#include "int/intmgr.h"
21:
22:
typedef void (*AG903_GPIOMgrIntHdr)(
void);
23:
24:
typedef struct _AG903_GPIOMgrIntParamt{
25:
AG903_GPIOMgrClbk clbk;
26: uint32_t target;
27: } AG903_GPIOMgrIntParam;
28:
29:
typedef struct _AG903_GPIOMgrChStat{
30: AG903_GPIOMgrIntParam intr[
AG903_GPIO_CALLBACK_NUM];
31: int32_t hdrid;
32: } AG903_GPIOMgrChStat;
33:
34:
35:
static AG903_GPIOMgrChStat GpioChStat[
AG903_GPIO_CH_NUM];
36:
37:
static void GPIOMgr_Init(uint8_t ch);
38:
static int32_t GPIOMgr_DeleteCallback(uint8_t ch, uint32_t num);
39:
static void GPIOMgr_Inthdr0(
void);
40:
static void GPIOMgr_Inthdr1(
void);
41:
static void GPIOMgr_Inthdr2(
void);
42:
static void GPIOMgr_Inthdr3(
void);
43:
static void GPIOMgr_IntProcess(uint8_t ch);
44:
45:
static const AG903_GPIOMgrIntHdr GpioIntHdr[
AG903_GPIO_CH_NUM] =
46: { GPIOMgr_Inthdr0, GPIOMgr_Inthdr1, GPIOMgr_Inthdr2, GPIOMgr_Inthdr3 };
47:
48:
49:
57: int32_t
AG903_GPIOMgrInit(
void)
58: {
59: int32_t retval =
AG903_ENONE;
60: uint32_t loop;
61:
62:
for(loop=0; loop<
AG903_GPIO_CH_NUM; loop++) {
63: GPIOMgr_Init(loop);
64: }
65:
66:
return retval;
67: }
68:
69:
79: int32_t
AG903_GPIOMgrSetByteData(uint8_t blknum, uint8_t data)
80: {
81: int32_t retval =
AG903_ENONE;
82: uint8_t ch;
83: uint8_t offset;
84:
85:
if(
AG903_GPIO_PORTBLK_TORTAL <= blknum) {
86:
return -
AG903_EINVAL;
87: }
88: ch = (blknum / 4);
89: offset = (blknum % 4);
90:
AG903_GPIOPrmSetByteData(ch, offset, data);
91:
92:
return retval;
93: }
94:
95:
106: int32_t
AG903_GPIOMgrSetPortData(uint8_t portch, uint32_t data, uint32_t target)
107: {
108: int32_t retval =
AG903_ENONE;
109: uint32_t set;
110: uint32_t clr;
111:
112:
if(
AG903_GPIO_CH_NUM <= portch) {
113:
return -
AG903_EINVAL;
114: }
115:
116: set = (data&target);
117: clr = (~data&target);
118:
119:
#if AG903_GPIO_USE_LDREX
120:
AG903_GPIOPrmModifyBit(portch, set, clr,
true);
121:
#else
122:
AG903_GPIOPrmModifyBit(portch, set, clr,
false);
123:
#endif
124:
125:
return retval;
126: }
127:
128:
138: int32_t
AG903_GPIOMgrGetByteData(uint8_t blknum, uint8_t* data)
139: {
140: int32_t retval =
AG903_ENONE;
141: uint8_t ch;
142: uint8_t offset;
143:
144:
if( (
AG903_GPIO_PORTBLK_TORTAL <= blknum) ||
145: (NULL == data) ){
146:
return -
AG903_EINVAL;
147: }
148: ch = (blknum / 4);
149: offset = (blknum % 4);
150:
AG903_GPIOPrmGetByteData(ch, offset, data);
151:
152:
return retval;
153: }
154:
155:
164: int32_t
AG903_GPIOMgrGetPortData(uint8_t portch, uint32_t* data)
165: {
166: int32_t retval =
AG903_ENONE;
167:
168:
if( (
AG903_GPIO_CH_NUM <= portch) ||
169: (NULL == data) ){
170:
return -
AG903_EINVAL;
171: }
172:
AG903_GPIOPrmGetPortData(portch, data);
173:
174:
return retval;
175: }
176:
177:
186: int32_t
AG903_GPIOMgrSetDirection(uint8_t portch, uint32_t direction)
187: {
188: int32_t retval =
AG903_ENONE;
189:
190:
if(
AG903_GPIO_CH_NUM <= portch) {
191:
return -
AG903_EINVAL;
192: }
193:
AG903_GPIOPrmSetDirection(portch, direction);
194:
195:
return retval;
196: }
197:
198:
207: int32_t
AG903_GPIOMgrGetDirection(uint8_t portch, uint32_t* direction)
208: {
209: int32_t retval =
AG903_ENONE;
210:
211:
if( (
AG903_GPIO_CH_NUM <= portch) ||
212: (NULL == direction) ){
213:
return -
AG903_EINVAL;
214: }
215:
AG903_GPIOPrmGetDirection(portch, direction);
216:
217:
return retval;
218: }
219:
220:
229: int32_t
AG903_GPIOMgrSetType(uint8_t portch, uint32_t type)
230: {
231: int32_t retval =
AG903_ENONE;
232:
233:
if(
AG903_GPIO_CH_NUM <= portch) {
234:
return -
AG903_EINVAL;
235: }
236:
AG903_GPIOPrmSetType(portch, type);
237:
238:
return retval;
239: }
240:
241:
250: int32_t
AG903_GPIOMgrGetType(uint8_t portch, uint32_t* type)
251: {
252: int32_t retval =
AG903_ENONE;
253:
254:
if( (
AG903_GPIO_CH_NUM <= portch) ||
255: (NULL == type) ){
256:
return -
AG903_EINVAL;
257: }
258:
AG903_GPIOPrmGetType(portch, type);
259:
260:
return retval;
261: }
262:
263:
272: int32_t
AG903_GPIOMgrSetPositiveDetect(uint8_t portch, uint32_t enable)
273: {
274: int32_t retval =
AG903_ENONE;
275:
276:
if(
AG903_GPIO_CH_NUM <= portch) {
277:
return -
AG903_EINVAL;
278: }
279:
AG903_GPIOPrmSetPosEdgeDetect(portch, enable);
280:
281:
return retval;
282: }
283:
284:
293: int32_t
AG903_GPIOMgrGetPositiveDetect(uint8_t portch, uint32_t* enable)
294: {
295: int32_t retval =
AG903_ENONE;
296:
297:
if( (
AG903_GPIO_CH_NUM <= portch) ||
298: (NULL == enable) ){
299:
return -
AG903_EINVAL;
300: }
301:
AG903_GPIOPrmGetPosEdgeDetect(portch, enable);
302:
303:
return retval;
304: }
305:
306:
315: int32_t
AG903_GPIOMgrSetNegativeDetect(uint8_t portch, uint32_t enable)
316: {
317: int32_t retval =
AG903_ENONE;
318:
319:
if(
AG903_GPIO_CH_NUM <= portch) {
320:
return -
AG903_EINVAL;
321: }
322:
AG903_GPIOPrmSetNegEdgeDetect(portch, enable);
323:
324:
return retval;
325: }
326:
327:
336: int32_t
AG903_GPIOMgrGetNegativeDetect(uint8_t portch, uint32_t* enable)
337: {
338: int32_t retval =
AG903_ENONE;
339:
340:
if( (
AG903_GPIO_CH_NUM <= portch) ||
341: (NULL == enable) ){
342:
return -
AG903_EINVAL;
343: }
344:
AG903_GPIOPrmGetNegEdgeDetect(portch, enable);
345:
346:
return retval;
347: }
348:
349:
358: int32_t
AG903_GPIOMgrSetMask(uint8_t portch, uint32_t mask)
359: {
360: int32_t retval =
AG903_ENONE;
361:
362:
if(
AG903_GPIO_CH_NUM <= portch) {
363:
return -
AG903_EINVAL;
364: }
365:
AG903_GPIOPrmSetMask(portch, mask);
366:
367:
return retval;
368: }
369:
370:
379: int32_t
AG903_GPIOMgrGetMask(uint8_t portch, uint32_t* mask)
380: {
381: int32_t retval =
AG903_ENONE;
382:
383:
if( (
AG903_GPIO_CH_NUM <= portch) ||
384: (NULL == mask) ){
385:
return -
AG903_EINVAL;
386: }
387:
AG903_GPIOPrmGetMask(portch, mask);
388:
389:
return retval;
390: }
391:
392:
401: int32_t
AG903_GPIOMgrGetEdgeDetect(uint8_t portch, uint32_t* status)
402: {
403: int32_t retval =
AG903_ENONE;
404:
405:
if( (
AG903_GPIO_CH_NUM <= portch) ||
406: (NULL == status) ){
407:
return -
AG903_EINVAL;
408: }
409:
AG903_GPIOPrmGetEdgeDetect(portch, status);
410:
411:
return retval;
412: }
413:
414:
424: int32_t
AG903_GPIOMgrClearEdgeDetect(uint8_t portch, uint32_t clrbit)
425: {
426: int32_t retval =
AG903_ENONE;
427:
428:
if(
AG903_GPIO_CH_NUM <= portch) {
429:
return -
AG903_EINVAL;
430: }
431:
AG903_GPIOPrmClearEdgeDetect(portch, clrbit);
432:
433:
return retval;
434: }
435:
436:
449: int32_t
AG903_GPIOMgrSetCallback(uint8_t portch, uint32_t target,
AG903_GPIOMgrClbk clbk)
450: {
451: int32_t retval =
AG903_ENONE;
452:
AG903_INTMgrHdrPrm inthdr;
453: int32_t hdrid;
454: uint32_t loop;
455:
456:
if( (
AG903_GPIO_CH_NUM <= portch) ||
457: (NULL == clbk) ){
458:
return -
AG903_EINVAL;
459: }
460:
461:
if(0 == GpioChStat[portch].hdrid) {
462: inthdr.atr =
AG903_INT_HLNG;
463: inthdr.intno =
AG903_IRQ40_GPIO0+portch;
464: inthdr.func = (
void*)GpioIntHdr[portch];
465: hdrid =
AG903_INTMgrSetHandler(&inthdr);
466:
if(0 >= hdrid) {
467:
return -
AG903_EFAULT;
468: }
469: GpioChStat[portch].hdrid = hdrid;
470:
AG903_INTMgrEnableInt(
AG903_IRQ40_GPIO0+portch);
471: }
472:
473:
do{
474:
if(
AG903_ENONE != retval) {
475:
break;
476: }
477:
478:
for(loop=0; loop<
AG903_GPIO_CALLBACK_NUM; loop++) {
479:
if(clbk == GpioChStat[portch].intr[loop].clbk) {
480: GpioChStat[portch].intr[loop].target |= target;
481:
break;
482: }
483: }
484:
if(
AG903_GPIO_CALLBACK_NUM > loop) {
485:
break;
486: }
487:
488:
for(loop=0; loop<
AG903_GPIO_CALLBACK_NUM; loop++) {
489:
if(NULL == GpioChStat[portch].intr[loop].clbk) {
490: GpioChStat[portch].intr[loop].clbk = clbk;
491: GpioChStat[portch].intr[loop].target = target;
492:
break;
493: }
494: }
495:
if(
AG903_GPIO_CALLBACK_NUM <= loop) {
496: retval = -
AG903_ENOBUFS;
497: }
498: }
while(0);
499:
500:
return retval;
501: }
502:
503:
514: int32_t
AG903_GPIOMgrClearCallback(uint8_t portch, uint32_t target,
AG903_GPIOMgrClbk clbk)
515: {
516: int32_t retval =
AG903_ENONE;
517: uint32_t loop;
518:
519:
if( (
AG903_GPIO_CH_NUM <= portch) ||
520: (NULL == clbk) ){
521:
return -
AG903_EINVAL;
522: }
523:
524:
for(loop=0; loop<
AG903_GPIO_CALLBACK_NUM; loop++) {
525:
if(clbk == GpioChStat[portch].intr[loop].clbk) {
526: GpioChStat[portch].intr[loop].target &= ~target;
527:
if(0 == target) {
528: GPIOMgr_DeleteCallback(portch, loop);
529: }
530:
break;
531: }
532: }
533:
if(
AG903_GPIO_CALLBACK_NUM <= loop) {
534: retval = -
AG903_EINVAL;
535: }
536:
537:
return retval;
538: }
539:
540:
544:
static void GPIOMgr_Init(uint8_t ch)
545: {
546: int32_t loop;
547:
for(loop=0; loop<
AG903_GPIO_CALLBACK_NUM; loop++) {
548: GpioChStat[ch].intr[loop].clbk = NULL;
549: GpioChStat[ch].intr[loop].target = 0;
550: }
551: GpioChStat[ch].hdrid = 0;
552:
553:
return;
554: }
555:
556:
561:
static int32_t GPIOMgr_DeleteCallback(uint8_t ch, uint32_t num)
562: {
563: int32_t retval =
AG903_ENONE;
564: uint32_t loop;
565:
566:
if( (
AG903_GPIO_CH_NUM <= ch) ||
567: (
AG903_GPIO_CALLBACK_NUM <= num) ){
568:
return -
AG903_EINVAL;
569: }
570:
571:
if((
AG903_GPIO_CALLBACK_NUM-1) <= num) {
572: GpioChStat[ch].intr[num].clbk = NULL;
573: }
574:
else {
575:
for(loop=num; loop<(
AG903_GPIO_CALLBACK_NUM-1); loop++) {
576: GpioChStat[ch].intr[loop] = GpioChStat[ch].intr[loop+1];
577:
if(NULL == GpioChStat[ch].intr[loop].clbk) {
578:
break;
579: }
580: }
581: }
582:
583:
return retval;
584: }
585:
586:
587:
590:
static void GPIOMgr_Inthdr0(
void)
591: {
592: GPIOMgr_IntProcess(0);
593:
return;
594: }
595:
596:
599:
static void GPIOMgr_Inthdr1(
void)
600: {
601: GPIOMgr_IntProcess(1);
602:
return;
603: }
604:
605:
608:
static void GPIOMgr_Inthdr2(
void)
609: {
610: GPIOMgr_IntProcess(2);
611:
return;
612: }
613:
614:
617:
static void GPIOMgr_Inthdr3(
void)
618: {
619: GPIOMgr_IntProcess(3);
620:
return;
621: }
622:
623:
626:
static void GPIOMgr_IntProcess(uint8_t ch)
627: {
628: uint32_t status = 0;
629: uint32_t val;
630: uint32_t loop;
631:
632:
AG903_GPIOPrmGetEdgeDetect(ch, &status);
633:
AG903_GPIOPrmClearEdgeDetect(ch, status);
634:
635:
for(loop=0; loop<
AG903_GPIO_CALLBACK_NUM; loop++) {
636: val = (status & GpioChStat[ch].intr[loop].target);
637:
if(0 != val) {
638: GpioChStat[ch].intr[loop].clbk(ch, val);
639: }
640:
if(NULL == GpioChStat[ch].intr[loop].clbk) {
641:
break;
642: }
643: }
644:
645:
return;
646: }